1 package org.apache.maven.model.interpolation;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.text.SimpleDateFormat;
24 import java.util.Arrays;
25 import java.util.Calendar;
26 import java.util.Collections;
27 import java.util.Date;
28 import java.util.HashMap;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Properties;
33 import java.util.TimeZone;
34
35 import org.apache.maven.api.model.Build;
36 import org.apache.maven.api.model.Dependency;
37 import org.apache.maven.api.model.Model;
38 import org.apache.maven.api.model.Organization;
39 import org.apache.maven.api.model.Repository;
40 import org.apache.maven.api.model.Resource;
41 import org.apache.maven.api.model.Scm;
42 import org.apache.maven.model.building.DefaultModelBuildingRequest;
43 import org.apache.maven.model.building.ModelBuildingRequest;
44 import org.apache.maven.model.building.SimpleProblemCollector;
45 import org.junit.jupiter.api.BeforeEach;
46 import org.junit.jupiter.api.Test;
47
48 import static org.junit.jupiter.api.Assertions.assertEquals;
49 import static org.junit.jupiter.api.Assertions.assertNotNull;
50 import static org.junit.jupiter.api.Assertions.assertTrue;
51
52
53
54
55 public abstract class AbstractModelInterpolatorTest
56 {
57 private Properties context;
58
59 @BeforeEach
60 public void setUp()
61 {
62 context = new Properties();
63 context.put( "basedir", "myBasedir" );
64 context.put( "project.baseUri", "myBaseUri" );
65 }
66
67
68 protected void assertProblemFree( SimpleProblemCollector collector )
69 {
70 assertEquals( 0, collector.getErrors().size(), "Expected no errors" );
71 assertEquals( 0, collector.getWarnings().size(), "Expected no warnings" );
72 assertEquals( 0, collector.getFatals().size(), "Expected no fatals" );
73 }
74
75 protected void assertCollectorState( int numFatals, int numErrors, int numWarnings, SimpleProblemCollector collector )
76 {
77 assertEquals( numErrors, collector.getErrors().size(), "Errors" );
78 assertEquals( numWarnings, collector.getWarnings().size(), "Warnings" );
79 assertEquals( numFatals, collector.getFatals().size(), "Fatals" );
80 }
81
82 private ModelBuildingRequest createModelBuildingRequest( Properties p )
83 {
84 ModelBuildingRequest config = new DefaultModelBuildingRequest();
85 if ( p != null )
86 {
87 config.setSystemProperties( p );
88 }
89 return config;
90 }
91
92 @Test
93 public void testDefaultBuildTimestampFormatShouldFormatTimeIn24HourFormat()
94 {
95 Calendar cal = Calendar.getInstance();
96 cal.setTimeZone( MavenBuildTimestamp.DEFAULT_BUILD_TIME_ZONE );
97 cal.set( Calendar.HOUR, 12 );
98 cal.set( Calendar.AM_PM, Calendar.AM );
99
100
101 cal.set( Calendar.HOUR_OF_DAY, 0 );
102 cal.set( Calendar.MINUTE, 16 );
103 cal.set( Calendar.SECOND, 0 );
104 cal.set( Calendar.YEAR, 1976 );
105 cal.set( Calendar.MONTH, Calendar.NOVEMBER );
106 cal.set( Calendar.DATE, 11 );
107
108 Date firstTestDate = cal.getTime();
109
110 cal.set( Calendar.HOUR, 11 );
111 cal.set( Calendar.AM_PM, Calendar.PM );
112
113
114 cal.set( Calendar.HOUR_OF_DAY, 23 );
115
116 Date secondTestDate = cal.getTime();
117
118 SimpleDateFormat format = new SimpleDateFormat( MavenBuildTimestamp.DEFAULT_BUILD_TIMESTAMP_FORMAT );
119 format.setTimeZone( MavenBuildTimestamp.DEFAULT_BUILD_TIME_ZONE );
120 assertEquals( "1976-11-11T00:16:00Z", format.format( firstTestDate ) );
121 assertEquals( "1976-11-11T23:16:00Z", format.format( secondTestDate ) );
122 }
123
124 @Test
125 public void testDefaultBuildTimestampFormatWithLocalTimeZoneMidnightRollover()
126 {
127 Calendar cal = Calendar.getInstance();
128 cal.setTimeZone( TimeZone.getTimeZone( "Europe/Berlin" ) );
129
130 cal.set( Calendar.HOUR_OF_DAY, 1 );
131 cal.set( Calendar.MINUTE, 16 );
132 cal.set( Calendar.SECOND, 0 );
133 cal.set( Calendar.YEAR, 2014 );
134 cal.set( Calendar.MONTH, Calendar.JUNE );
135 cal.set( Calendar.DATE, 16 );
136
137 Date firstTestDate = cal.getTime();
138
139 cal.set( Calendar.MONTH, Calendar.NOVEMBER );
140
141 Date secondTestDate = cal.getTime();
142
143 SimpleDateFormat format = new SimpleDateFormat( MavenBuildTimestamp.DEFAULT_BUILD_TIMESTAMP_FORMAT );
144 format.setTimeZone( MavenBuildTimestamp.DEFAULT_BUILD_TIME_ZONE );
145 assertEquals( "2014-06-15T23:16:00Z", format.format( firstTestDate ) );
146 assertEquals( "2014-11-16T00:16:00Z", format.format( secondTestDate ) );
147 }
148
149 @Test
150 public void testShouldNotThrowExceptionOnReferenceToNonExistentValue() throws Exception
151 {
152 Scm scm = Scm.newBuilder().connection( "${test}/somepath" ).build();
153 Model model = Model.newBuilder().scm( scm ).build();
154
155 ModelInterpolator interpolator = createInterpolator();
156
157 final SimpleProblemCollector collector = new SimpleProblemCollector();
158 Model out = interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ),
159 collector );
160
161 assertProblemFree( collector );
162 assertEquals( "${test}/somepath", out.getScm().getConnection() );
163 }
164
165 @Test
166 public void testShouldThrowExceptionOnRecursiveScmConnectionReference() throws Exception
167 {
168 Scm scm = Scm.newBuilder().connection( "${project.scm.connection}/somepath" ).build();
169 Model model = Model.newBuilder().scm( scm ).build();
170
171 ModelInterpolator interpolator = createInterpolator();
172
173 final SimpleProblemCollector collector = new SimpleProblemCollector();
174 interpolator.interpolateModel( model, null, createModelBuildingRequest( context ), collector );
175 assertCollectorState( 0, 1, 0, collector );
176 }
177
178 @Test
179 public void testShouldNotThrowExceptionOnReferenceToValueContainingNakedExpression() throws Exception
180 {
181 Scm scm = Scm.newBuilder().connection( "${test}/somepath" ).build();
182 Map<String, String> props = new HashMap<>();
183 props.put( "test", "test" );
184 Model model = Model.newBuilder().scm( scm ).properties( props ).build();
185
186 ModelInterpolator interpolator = createInterpolator();
187
188 final SimpleProblemCollector collector = new SimpleProblemCollector();
189 Model out = interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ),
190 collector );
191
192 assertProblemFree( collector );
193
194 assertEquals( "test/somepath", out.getScm().getConnection() );
195 }
196
197 @Test
198 public void shouldInterpolateOrganizationNameCorrectly() throws Exception
199 {
200 String orgName = "MyCo";
201
202 Model model = Model.newBuilder().name( "${project.organization.name} Tools" )
203 .organization( Organization.newBuilder().name( orgName ).build() )
204 .build();
205
206 ModelInterpolator interpolator = createInterpolator();
207
208 Model out = interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ),
209 new SimpleProblemCollector() );
210
211 assertEquals( orgName + " Tools", out.getName() );
212 }
213
214 @Test
215 public void shouldInterpolateDependencyVersionToSetSameAsProjectVersion() throws Exception
216 {
217 Model model = Model.newBuilder().version( "3.8.1" )
218 .dependencies( Collections.singletonList( Dependency.newBuilder().version( "${project.version}" ).build() ) )
219 .build();
220
221 ModelInterpolator interpolator = createInterpolator();
222
223 final SimpleProblemCollector collector = new SimpleProblemCollector();
224 Model out = interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ),
225 collector );
226 assertCollectorState( 0, 0, 0, collector );
227
228 assertEquals( "3.8.1", ( out.getDependencies().get( 0 ) ).getVersion() );
229 }
230
231 @Test
232 public void testShouldNotInterpolateDependencyVersionWithInvalidReference() throws Exception
233 {
234 Model model = Model.newBuilder().version( "3.8.1" )
235 .dependencies( Collections.singletonList( Dependency.newBuilder().version( "${something}" ).build() ) )
236 .build();
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253 ModelInterpolator interpolator = createInterpolator();
254
255 final SimpleProblemCollector collector = new SimpleProblemCollector();
256 Model out = interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ),
257 collector );
258 assertProblemFree( collector );
259
260 assertEquals( "${something}", ( out.getDependencies().get( 0 ) ).getVersion() );
261 }
262
263 @Test
264 public void testTwoReferences() throws Exception
265 {
266 Model model = Model.newBuilder().version( "3.8.1" ).artifactId( "foo" )
267 .dependencies( Collections.singletonList(
268 Dependency.newBuilder().version( "${project.artifactId}-${project.version}" ).build() ) )
269 .build();
270
271 ModelInterpolator interpolator = createInterpolator();
272
273 final SimpleProblemCollector collector = new SimpleProblemCollector();
274 Model out = interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ),
275 collector );
276 assertCollectorState( 0, 0, 0, collector );
277
278 assertEquals( "foo-3.8.1", ( out.getDependencies().get( 0 ) ).getVersion() );
279 }
280
281 @Test
282 public void testBasedir() throws Exception
283 {
284 Model model = Model.newBuilder().version( "3.8.1" ).artifactId( "foo" )
285 .repositories( Collections.singletonList(
286 Repository.newBuilder().url( "file://localhost/${basedir}/temp-repo" ).build() ) )
287 .build();
288
289 ModelInterpolator interpolator = createInterpolator();
290
291 final SimpleProblemCollector collector = new SimpleProblemCollector();
292 Model out = interpolator.interpolateModel( model, null, createModelBuildingRequest( context ), collector );
293 assertProblemFree( collector );
294
295 assertEquals( "file://localhost/myBasedir/temp-repo", ( out.getRepositories().get( 0 ) ).getUrl() );
296 }
297
298 @Test
299 public void testBaseUri() throws Exception
300 {
301 Model model = Model.newBuilder().version( "3.8.1" ).artifactId( "foo" )
302 .repositories( Collections.singletonList(
303 Repository.newBuilder().url( "${project.baseUri}/temp-repo" ).build() ) )
304 .build();
305
306 ModelInterpolator interpolator = createInterpolator();
307
308 final SimpleProblemCollector collector = new SimpleProblemCollector();
309 Model out = interpolator.interpolateModel( model, null, createModelBuildingRequest( context ), collector );
310 assertProblemFree( collector );
311
312 assertEquals( "myBaseUri/temp-repo", ( out.getRepositories().get( 0 ) ).getUrl() );
313 }
314
315 @Test
316 public void testEnvars() throws Exception
317 {
318 Properties context = new Properties();
319 context.put( "env.HOME", "/path/to/home" );
320
321 Map<String, String> modelProperties = new HashMap<>();
322 modelProperties.put( "outputDirectory", "${env.HOME}" );
323
324 Model model = Model.newBuilder().properties( modelProperties ).build();
325
326 ModelInterpolator interpolator = createInterpolator();
327
328 final SimpleProblemCollector collector = new SimpleProblemCollector();
329 Model out = interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ),
330 collector );
331 assertProblemFree( collector );
332
333 assertEquals( "/path/to/home", out.getProperties().get( "outputDirectory" ) );
334 }
335
336 @Test
337 public void envarExpressionThatEvaluatesToNullReturnsTheLiteralString() throws Exception
338 {
339
340 Map<String, String> modelProperties = new HashMap<>();
341 modelProperties.put( "outputDirectory", "${env.DOES_NOT_EXIST}" );
342
343 Model model = Model.newBuilder().properties( modelProperties ).build();
344
345 ModelInterpolator interpolator = createInterpolator();
346
347 final SimpleProblemCollector collector = new SimpleProblemCollector();
348 Model out = interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ),
349 collector );
350 assertProblemFree( collector );
351
352 assertEquals( out.getProperties().get( "outputDirectory" ), "${env.DOES_NOT_EXIST}" );
353 }
354
355 @Test
356 public void expressionThatEvaluatesToNullReturnsTheLiteralString() throws Exception
357 {
358 Map<String, String> modelProperties = new HashMap<>();
359 modelProperties.put( "outputDirectory", "${DOES_NOT_EXIST}" );
360
361 Model model = Model.newBuilder().properties( modelProperties ).build();
362
363 ModelInterpolator interpolator = createInterpolator();
364
365 final SimpleProblemCollector collector = new SimpleProblemCollector();
366 Model out = interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ),
367 collector );
368 assertProblemFree( collector );
369
370 assertEquals( out.getProperties().get( "outputDirectory" ), "${DOES_NOT_EXIST}" );
371 }
372
373 @Test
374 public void shouldInterpolateSourceDirectoryReferencedFromResourceDirectoryCorrectly() throws Exception
375 {
376 Model model = Model.newBuilder()
377 .build( Build.newBuilder()
378 .sourceDirectory( "correct" )
379 .resources( Arrays.asList(
380 Resource.newBuilder().directory( "${project.build.sourceDirectory}" ).build()
381 ) )
382 .build() )
383 .build();
384
385 ModelInterpolator interpolator = createInterpolator();
386
387 final SimpleProblemCollector collector = new SimpleProblemCollector();
388 Model out = interpolator.interpolateModel( model, null, createModelBuildingRequest( context ), collector );
389 assertCollectorState( 0, 0, 0, collector );
390
391
392 List<Resource> outResources = out.getBuild().getResources();
393 Iterator<Resource> resIt = outResources.iterator();
394
395 assertEquals( model.getBuild().getSourceDirectory(), resIt.next().getDirectory() );
396 }
397
398 @Test
399 public void shouldInterpolateUnprefixedBasedirExpression() throws Exception
400 {
401 File basedir = new File( "/test/path" );
402 Model model = Model.newBuilder()
403 .dependencies( Collections.singletonList(
404 Dependency.newBuilder().systemPath( "${basedir}/artifact.jar" ).build()
405 ) ).build();
406
407 ModelInterpolator interpolator = createInterpolator();
408
409 final SimpleProblemCollector collector = new SimpleProblemCollector();
410 Model result = interpolator.interpolateModel( model, basedir, createModelBuildingRequest( context ),
411 collector );
412 assertProblemFree( collector );
413
414
415 List<Dependency> rDeps = result.getDependencies();
416 assertNotNull( rDeps );
417 assertEquals( 1, rDeps.size() );
418 assertEquals( new File( basedir, "artifact.jar" ).getAbsolutePath(),
419 new File( rDeps.get( 0 ).getSystemPath() ).getAbsolutePath() );
420 }
421
422 @Test
423 public void testRecursiveExpressionCycleNPE() throws Exception
424 {
425 Map<String, String> props = new HashMap<>();
426 props.put( "aa", "${bb}" );
427 props.put( "bb", "${aa}" );
428 DefaultModelBuildingRequest request = new DefaultModelBuildingRequest();
429
430 Model model = Model.newBuilder().properties( props ).build();
431
432 SimpleProblemCollector collector = new SimpleProblemCollector();
433 ModelInterpolator interpolator = createInterpolator();
434 interpolator.interpolateModel( model, null, request, collector );
435
436 assertCollectorState( 0, 2, 0, collector );
437 assertTrue( collector.getErrors().get( 0 ).contains( "Detected the following recursive expression cycle" ) );
438 }
439
440 @Test
441 public void testRecursiveExpressionCycleBaseDir() throws Exception
442 {
443 Map<String, String> props = new HashMap<>();
444 props.put( "basedir", "${basedir}" );
445 DefaultModelBuildingRequest request = new DefaultModelBuildingRequest();
446
447 Model model = Model.newBuilder().properties( props ).build();
448
449 SimpleProblemCollector collector = new SimpleProblemCollector();
450 ModelInterpolator interpolator = createInterpolator();
451 interpolator.interpolateModel( model, null, request, collector );
452
453 assertCollectorState( 0, 1, 0, collector );
454 assertEquals(
455 "Resolving expression: '${basedir}': Detected the following recursive expression cycle in 'basedir': [basedir]",
456 collector.getErrors().get( 0 ) );
457 }
458
459 @Test
460 public void shouldIgnorePropertiesWithPomPrefix() throws Exception
461 {
462 final String orgName = "MyCo";
463 final String expectedName = "${pom.organization.name} Tools";
464
465 Model model = Model.newBuilder()
466 .name( expectedName )
467 .organization( Organization.newBuilder().name( orgName ).build() )
468 .build();
469
470 ModelInterpolator interpolator = createInterpolator();
471 SimpleProblemCollector collector = new SimpleProblemCollector();
472 Model out = interpolator.interpolateModel( model, null, createModelBuildingRequest( context ),
473 collector );
474
475 assertCollectorState( 0, 0, 0, collector );
476 assertEquals( out.getName(), expectedName );
477 }
478
479 protected abstract ModelInterpolator createInterpolator() throws Exception;
480
481 }