1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.model.interpolation;
20
21 import java.io.File;
22 import java.text.SimpleDateFormat;
23 import java.util.Calendar;
24 import java.util.Date;
25 import java.util.Iterator;
26 import java.util.List;
27 import java.util.Properties;
28 import java.util.TimeZone;
29
30 import org.apache.maven.model.Build;
31 import org.apache.maven.model.Dependency;
32 import org.apache.maven.model.Model;
33 import org.apache.maven.model.Organization;
34 import org.apache.maven.model.Plugin;
35 import org.apache.maven.model.Repository;
36 import org.apache.maven.model.Resource;
37 import org.apache.maven.model.Scm;
38 import org.apache.maven.model.building.DefaultModelBuildingRequest;
39 import org.apache.maven.model.building.ModelBuildingRequest;
40 import org.apache.maven.model.building.SimpleProblemCollector;
41 import org.apache.maven.model.path.PathTranslator;
42 import org.codehaus.plexus.util.xml.Xpp3Dom;
43 import org.junit.jupiter.api.Test;
44
45 import static org.junit.jupiter.api.Assertions.assertEquals;
46 import static org.junit.jupiter.api.Assertions.assertNotNull;
47
48
49
50
51 public abstract class AbstractModelInterpolatorTest {
52 private Properties context;
53
54 protected void setUp() throws Exception {
55 context = new Properties();
56 context.put("basedir", "myBasedir");
57 context.put("project.baseUri", "myBaseUri");
58 }
59
60 protected void assertProblemFree(SimpleProblemCollector collector) {
61 assertEquals(0, collector.getErrors().size(), "Expected no errors");
62 assertEquals(0, collector.getWarnings().size(), "Expected no warnings");
63 assertEquals(0, collector.getFatals().size(), "Expected no fatals");
64 }
65
66
67
68
69 @Deprecated
70 protected void assertColllectorState(
71 int numFatals, int numErrors, int numWarnings, SimpleProblemCollector collector) {
72 assertEquals(numErrors, collector.getErrors().size(), "Errors");
73 assertEquals(numWarnings, collector.getWarnings().size(), "Warnings");
74 assertEquals(numFatals, collector.getFatals().size(), "Fatals");
75 }
76
77 protected void assertCollectorState(
78 int numFatals, int numErrors, int numWarnings, SimpleProblemCollector collector) {
79 assertColllectorState(numFatals, numErrors, numWarnings, collector);
80 }
81
82 private ModelBuildingRequest createModelBuildingRequest(Properties p) {
83 ModelBuildingRequest config = new DefaultModelBuildingRequest();
84 if (p != null) {
85 config.setSystemProperties(p);
86 }
87 return config;
88 }
89
90 @Test
91 public void testDefaultBuildTimestampFormatShouldFormatTimeIn24HourFormat() {
92 Calendar cal = Calendar.getInstance();
93 cal.setTimeZone(MavenBuildTimestamp.DEFAULT_BUILD_TIME_ZONE);
94 cal.set(Calendar.HOUR, 12);
95 cal.set(Calendar.AM_PM, Calendar.AM);
96
97
98 cal.set(Calendar.HOUR_OF_DAY, 0);
99 cal.set(Calendar.MINUTE, 16);
100 cal.set(Calendar.SECOND, 0);
101 cal.set(Calendar.YEAR, 1976);
102 cal.set(Calendar.MONTH, Calendar.NOVEMBER);
103 cal.set(Calendar.DATE, 11);
104
105 Date firstTestDate = cal.getTime();
106
107 cal.set(Calendar.HOUR, 11);
108 cal.set(Calendar.AM_PM, Calendar.PM);
109
110
111 cal.set(Calendar.HOUR_OF_DAY, 23);
112
113 Date secondTestDate = cal.getTime();
114
115 SimpleDateFormat format = new SimpleDateFormat(MavenBuildTimestamp.DEFAULT_BUILD_TIMESTAMP_FORMAT);
116 format.setTimeZone(MavenBuildTimestamp.DEFAULT_BUILD_TIME_ZONE);
117 assertEquals("1976-11-11T00:16:00Z", format.format(firstTestDate));
118 assertEquals("1976-11-11T23:16:00Z", format.format(secondTestDate));
119 }
120
121 @Test
122 public void testDefaultBuildTimestampFormatWithLocalTimeZoneMidnightRollover() {
123 Calendar cal = Calendar.getInstance();
124 cal.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
125
126 cal.set(Calendar.HOUR_OF_DAY, 1);
127 cal.set(Calendar.MINUTE, 16);
128 cal.set(Calendar.SECOND, 0);
129 cal.set(Calendar.YEAR, 2014);
130 cal.set(Calendar.MONTH, Calendar.JUNE);
131 cal.set(Calendar.DATE, 16);
132
133 Date firstTestDate = cal.getTime();
134
135 cal.set(Calendar.MONTH, Calendar.NOVEMBER);
136
137 Date secondTestDate = cal.getTime();
138
139 SimpleDateFormat format = new SimpleDateFormat(MavenBuildTimestamp.DEFAULT_BUILD_TIMESTAMP_FORMAT);
140 format.setTimeZone(MavenBuildTimestamp.DEFAULT_BUILD_TIME_ZONE);
141 assertEquals("2014-06-15T23:16:00Z", format.format(firstTestDate));
142 assertEquals("2014-11-16T00:16:00Z", format.format(secondTestDate));
143 }
144
145 @Test
146 public void testShouldNotThrowExceptionOnReferenceToNonExistentValue() throws Exception {
147 Model model = new Model();
148
149 Scm scm = new Scm();
150 scm.setConnection("${test}/somepath");
151
152 model.setScm(scm);
153
154 ModelInterpolator interpolator = createInterpolator();
155
156 final SimpleProblemCollector collector = new SimpleProblemCollector();
157 Model out = interpolator.interpolateModel(model, new File("."), createModelBuildingRequest(context), collector);
158
159 assertProblemFree(collector);
160 assertEquals("${test}/somepath", out.getScm().getConnection());
161 }
162
163 @Test
164 public void testShouldThrowExceptionOnRecursiveScmConnectionReference() throws Exception {
165 Model model = new Model();
166
167 Scm scm = new Scm();
168 scm.setConnection("${project.scm.connection}/somepath");
169
170 model.setScm(scm);
171
172 try {
173 ModelInterpolator interpolator = createInterpolator();
174
175 final SimpleProblemCollector collector = new SimpleProblemCollector();
176 interpolator.interpolateModel(model, null, createModelBuildingRequest(context), collector);
177 assertCollectorState(0, 1, 0, collector);
178 } catch (Exception e) {
179
180 }
181 }
182
183 @Test
184 public void testShouldNotThrowExceptionOnReferenceToValueContainingNakedExpression() throws Exception {
185 Model model = new Model();
186
187 Scm scm = new Scm();
188 scm.setConnection("${test}/somepath");
189
190 model.setScm(scm);
191
192 model.addProperty("test", "test");
193
194 ModelInterpolator interpolator = createInterpolator();
195
196 final SimpleProblemCollector collector = new SimpleProblemCollector();
197 Model out = interpolator.interpolateModel(model, new File("."), createModelBuildingRequest(context), collector);
198
199 assertProblemFree(collector);
200
201 assertEquals("test/somepath", out.getScm().getConnection());
202 }
203
204 @Test
205 public void testShouldInterpolateOrganizationNameCorrectly() throws Exception {
206 String orgName = "MyCo";
207
208 Model model = new Model();
209 model.setName("${pom.organization.name} Tools");
210
211 Organization org = new Organization();
212 org.setName(orgName);
213
214 model.setOrganization(org);
215
216 ModelInterpolator interpolator = createInterpolator();
217
218 Model out = interpolator.interpolateModel(
219 model, new File("."), createModelBuildingRequest(context), new SimpleProblemCollector());
220
221 assertEquals(orgName + " Tools", out.getName());
222 }
223
224 @Test
225 public void testShouldInterpolateDependencyVersionToSetSameAsProjectVersion() throws Exception {
226 Model model = new Model();
227 model.setVersion("3.8.1");
228
229 Dependency dep = new Dependency();
230 dep.setVersion("${version}");
231
232 model.addDependency(dep);
233
234 ModelInterpolator interpolator = createInterpolator();
235
236 final SimpleProblemCollector collector = new SimpleProblemCollector();
237 Model out = interpolator.interpolateModel(model, new File("."), createModelBuildingRequest(context), collector);
238 assertCollectorState(0, 0, 1, collector);
239
240 assertEquals("3.8.1", (out.getDependencies().get(0)).getVersion());
241 }
242
243 @Test
244 public void testShouldNotInterpolateDependencyVersionWithInvalidReference() throws Exception {
245 Model model = new Model();
246 model.setVersion("3.8.1");
247
248 Dependency dep = new Dependency();
249 dep.setVersion("${something}");
250
251 model.addDependency(dep);
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268 ModelInterpolator interpolator = createInterpolator();
269
270 final SimpleProblemCollector collector = new SimpleProblemCollector();
271 Model out = interpolator.interpolateModel(model, new File("."), createModelBuildingRequest(context), collector);
272 assertProblemFree(collector);
273
274 assertEquals("${something}", (out.getDependencies().get(0)).getVersion());
275 }
276
277 @Test
278 public void testTwoReferences() throws Exception {
279 Model model = new Model();
280 model.setVersion("3.8.1");
281 model.setArtifactId("foo");
282
283 Dependency dep = new Dependency();
284 dep.setVersion("${artifactId}-${version}");
285
286 model.addDependency(dep);
287
288 ModelInterpolator interpolator = createInterpolator();
289
290 final SimpleProblemCollector collector = new SimpleProblemCollector();
291 Model out = interpolator.interpolateModel(model, new File("."), createModelBuildingRequest(context), collector);
292 assertCollectorState(0, 0, 2, collector);
293
294 assertEquals("foo-3.8.1", (out.getDependencies().get(0)).getVersion());
295 }
296
297 @Test
298 public void testBasedir() throws Exception {
299 Model model = new Model();
300 model.setVersion("3.8.1");
301 model.setArtifactId("foo");
302
303 Repository repository = new Repository();
304
305 repository.setUrl("file://localhost/${basedir}/temp-repo");
306
307 model.addRepository(repository);
308
309 ModelInterpolator interpolator = createInterpolator();
310
311 final SimpleProblemCollector collector = new SimpleProblemCollector();
312 Model out = interpolator.interpolateModel(model, null, createModelBuildingRequest(context), collector);
313 assertProblemFree(collector);
314
315 assertEquals(
316 "file://localhost/myBasedir/temp-repo", (out.getRepositories().get(0)).getUrl());
317 }
318
319 @Test
320 public void testBaseUri() throws Exception {
321 Model model = new Model();
322 model.setVersion("3.8.1");
323 model.setArtifactId("foo");
324
325 Repository repository = new Repository();
326
327 repository.setUrl("${project.baseUri}/temp-repo");
328
329 model.addRepository(repository);
330
331 ModelInterpolator interpolator = createInterpolator();
332
333 final SimpleProblemCollector collector = new SimpleProblemCollector();
334 Model out = interpolator.interpolateModel(model, null, createModelBuildingRequest(context), collector);
335 assertProblemFree(collector);
336
337 assertEquals("myBaseUri/temp-repo", (out.getRepositories().get(0)).getUrl());
338 }
339
340 @Test
341 public void testEnvars() throws Exception {
342 Properties context = new Properties();
343
344 context.put("env.HOME", "/path/to/home");
345
346 Model model = new Model();
347
348 Properties modelProperties = new Properties();
349
350 modelProperties.setProperty("outputDirectory", "${env.HOME}");
351
352 model.setProperties(modelProperties);
353
354 ModelInterpolator interpolator = createInterpolator();
355
356 final SimpleProblemCollector collector = new SimpleProblemCollector();
357 Model out = interpolator.interpolateModel(model, new File("."), createModelBuildingRequest(context), collector);
358 assertProblemFree(collector);
359
360 assertEquals("/path/to/home", out.getProperties().getProperty("outputDirectory"));
361 }
362
363 @Test
364 public void testMinimalValidationInterpolationUsesRestrictedPropertySet() throws Exception {
365 Properties context = new Properties();
366 context.put("env.SOME_VAR", "some-value");
367 context.put("some.property", "other-value");
368 context.put("java.version", "21");
369
370 Model model = new Model();
371
372 Properties modelProperties = new Properties();
373 modelProperties.setProperty("envDir", "${env.SOME_VAR}");
374 modelProperties.setProperty("propDir", "${some.property}");
375 modelProperties.setProperty("jdk", "${java.version}");
376
377 model.setProperties(modelProperties);
378
379 ModelInterpolator interpolator = createInterpolator();
380
381 final SimpleProblemCollector collector = new SimpleProblemCollector();
382 ModelBuildingRequest config = createModelBuildingRequest(context);
383 config.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL);
384 Model out = interpolator.interpolateModel(model, new File("."), config, collector);
385 assertProblemFree(collector);
386
387
388
389
390 assertEquals("${env.SOME_VAR}", out.getProperties().getProperty("envDir"));
391 assertEquals("${some.property}", out.getProperties().getProperty("propDir"));
392
393 assertEquals("21", out.getProperties().getProperty("jdk"));
394 }
395
396 @Test
397 public void testFullInterpolationOptOutRestoresPreviousBehaviorAtMinimalValidationLevel() throws Exception {
398 Properties context = new Properties();
399 context.put("env.SOME_VAR", "some-value");
400 context.put(AbstractStringBasedModelInterpolator.FULL_EXTERNAL_INTERPOLATION_PROPERTY, "true");
401
402 Model model = new Model();
403
404 Properties modelProperties = new Properties();
405 modelProperties.setProperty("envDir", "${env.SOME_VAR}");
406
407 model.setProperties(modelProperties);
408
409 ModelInterpolator interpolator = createInterpolator();
410
411 final SimpleProblemCollector collector = new SimpleProblemCollector();
412 ModelBuildingRequest config = createModelBuildingRequest(context);
413 config.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL);
414 Model out = interpolator.interpolateModel(model, new File("."), config, collector);
415 assertProblemFree(collector);
416
417 assertEquals("some-value", out.getProperties().getProperty("envDir"));
418 }
419
420 @Test
421 public void testEnvarsStillInterpolatedAtStrictValidationLevel() throws Exception {
422 Properties context = new Properties();
423 context.put("env.SOME_VAR", "some-value");
424 context.put("some.property", "other-value");
425
426 Model model = new Model();
427
428 Properties modelProperties = new Properties();
429 modelProperties.setProperty("envDir", "${env.SOME_VAR}");
430 modelProperties.setProperty("propDir", "${some.property}");
431
432 model.setProperties(modelProperties);
433
434 ModelInterpolator interpolator = createInterpolator();
435
436 final SimpleProblemCollector collector = new SimpleProblemCollector();
437 ModelBuildingRequest config = createModelBuildingRequest(context);
438 config.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_STRICT);
439 Model out = interpolator.interpolateModel(model, new File("."), config, collector);
440 assertProblemFree(collector);
441
442
443
444 assertEquals("some-value", out.getProperties().getProperty("envDir"));
445 assertEquals("other-value", out.getProperties().getProperty("propDir"));
446 }
447
448 @Test
449 public void testEnvarExpressionThatEvaluatesToNullReturnsTheLiteralString() throws Exception {
450 Model model = new Model();
451
452 Properties modelProperties = new Properties();
453
454 modelProperties.setProperty("outputDirectory", "${env.DOES_NOT_EXIST}");
455
456 model.setProperties(modelProperties);
457
458 ModelInterpolator interpolator = createInterpolator();
459
460 final SimpleProblemCollector collector = new SimpleProblemCollector();
461 Model out = interpolator.interpolateModel(model, new File("."), createModelBuildingRequest(context), collector);
462 assertProblemFree(collector);
463
464 assertEquals(out.getProperties().getProperty("outputDirectory"), "${env.DOES_NOT_EXIST}");
465 }
466
467 @Test
468 public void testExpressionThatEvaluatesToNullReturnsTheLiteralString() throws Exception {
469 Model model = new Model();
470
471 Properties modelProperties = new Properties();
472
473 modelProperties.setProperty("outputDirectory", "${DOES_NOT_EXIST}");
474
475 model.setProperties(modelProperties);
476
477 ModelInterpolator interpolator = createInterpolator();
478
479 final SimpleProblemCollector collector = new SimpleProblemCollector();
480 Model out = interpolator.interpolateModel(model, new File("."), createModelBuildingRequest(context), collector);
481 assertProblemFree(collector);
482
483 assertEquals(out.getProperties().getProperty("outputDirectory"), "${DOES_NOT_EXIST}");
484 }
485
486 @Test
487 public void testShouldInterpolateSourceDirectoryReferencedFromResourceDirectoryCorrectly() throws Exception {
488 Model model = new Model();
489
490 Build build = new Build();
491 build.setSourceDirectory("correct");
492
493 Resource res = new Resource();
494 res.setDirectory("${project.build.sourceDirectory}");
495
496 build.addResource(res);
497
498 Resource res2 = new Resource();
499 res2.setDirectory("${pom.build.sourceDirectory}");
500
501 build.addResource(res2);
502
503 Resource res3 = new Resource();
504 res3.setDirectory("${build.sourceDirectory}");
505
506 build.addResource(res3);
507
508 model.setBuild(build);
509
510 ModelInterpolator interpolator = createInterpolator();
511
512 final SimpleProblemCollector collector = new SimpleProblemCollector();
513 Model out = interpolator.interpolateModel(model, null, createModelBuildingRequest(context), collector);
514 assertCollectorState(0, 0, 2, collector);
515
516 List<Resource> outResources = out.getBuild().getResources();
517 Iterator<Resource> resIt = outResources.iterator();
518
519 assertEquals(build.getSourceDirectory(), resIt.next().getDirectory());
520 assertEquals(build.getSourceDirectory(), resIt.next().getDirectory());
521 assertEquals(build.getSourceDirectory(), resIt.next().getDirectory());
522 }
523
524 @Test
525 public void testShouldInterpolateUnprefixedBasedirExpression() throws Exception {
526 File basedir = new File("/test/path");
527 Model model = new Model();
528 Dependency dep = new Dependency();
529 dep.setSystemPath("${basedir}/artifact.jar");
530
531 model.addDependency(dep);
532
533 ModelInterpolator interpolator = createInterpolator();
534
535 final SimpleProblemCollector collector = new SimpleProblemCollector();
536 Model result = interpolator.interpolateModel(model, basedir, createModelBuildingRequest(context), collector);
537 assertProblemFree(collector);
538
539 List<Dependency> rDeps = result.getDependencies();
540 assertNotNull(rDeps);
541 assertEquals(1, rDeps.size());
542 assertEquals(
543 new File(basedir, "artifact.jar").getAbsolutePath(),
544 new File(rDeps.get(0).getSystemPath()).getAbsolutePath());
545 }
546
547 @Test
548 public void testRecursiveExpressionCycleInPluginConfiguration() throws Exception {
549
550
551 Model model = new Model();
552 model.addProperty("prop", "${prop}");
553
554 Xpp3Dom configuration = new Xpp3Dom("configuration");
555 Xpp3Dom filter = new Xpp3Dom("filter");
556 filter.setAttribute("token", "key");
557 filter.setAttribute("value", "${prop}");
558 filter.setValue("${prop}");
559 configuration.addChild(filter);
560
561 Plugin plugin = new Plugin();
562 plugin.setArtifactId("maven-antrun-plugin");
563 plugin.setConfiguration(configuration);
564
565 Build build = new Build();
566 build.addPlugin(plugin);
567 model.setBuild(build);
568
569 SimpleProblemCollector collector = new SimpleProblemCollector();
570 ModelInterpolator interpolator = createInterpolator();
571 Model out = interpolator.interpolateModel(model, null, createModelBuildingRequest(context), collector);
572
573 assertNotNull(out);
574 assertCollectorState(0, 3, 0, collector);
575 Xpp3Dom outConfig = (Xpp3Dom) out.getBuild().getPlugins().get(0).getConfiguration();
576 assertEquals("${prop}", outConfig.getChild("filter").getAttribute("value"));
577 assertEquals("${prop}", outConfig.getChild("filter").getValue());
578 }
579
580 protected abstract ModelInterpolator createInterpolator(PathTranslator translator) throws Exception;
581
582 protected abstract ModelInterpolator createInterpolator() throws Exception;
583 }