001package org.apache.maven.model.interpolation;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *  http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import org.apache.maven.model.Build;
023import org.apache.maven.model.Dependency;
024import org.apache.maven.model.Model;
025import org.apache.maven.model.Organization;
026import org.apache.maven.model.Repository;
027import org.apache.maven.model.Resource;
028import org.apache.maven.model.Scm;
029import org.apache.maven.model.building.DefaultModelBuildingRequest;
030import org.apache.maven.model.building.ModelBuildingRequest;
031import org.apache.maven.model.building.SimpleProblemCollector;
032import org.apache.maven.model.path.PathTranslator;
033import org.codehaus.plexus.PlexusTestCase;
034
035import java.io.File;
036import java.text.SimpleDateFormat;
037import java.util.Calendar;
038import java.util.Date;
039import java.util.Iterator;
040import java.util.List;
041import java.util.Properties;
042import java.util.TimeZone;
043
044/**
045 * @author jdcasey
046 */
047public abstract class AbstractModelInterpolatorTest
048    extends PlexusTestCase
049{
050    private Properties context;
051
052    protected void setUp()
053        throws Exception
054    {
055        super.setUp();
056
057        context = new Properties();
058        context.put( "basedir", "myBasedir" );
059        context.put( "project.baseUri", "myBaseUri" );
060    }
061
062
063    protected void assertProblemFree( SimpleProblemCollector collector )
064    {
065        assertEquals( "Expected no errors", 0, collector.getErrors().size() );
066        assertEquals( "Expected no warnings", 0, collector.getWarnings().size() );
067        assertEquals( "Expected no fatals", 0, collector.getFatals().size() );
068    }
069
070    protected void assertColllectorState( int numFatals, int numErrors, int numWarnings,
071                                          SimpleProblemCollector collector )
072    {
073        assertEquals( "Errors",  numErrors, collector.getErrors().size() );
074        assertEquals( "Warnings", numWarnings, collector.getWarnings().size() );
075        assertEquals( "Fatals", numFatals, collector.getFatals().size() );
076    }
077
078    private ModelBuildingRequest createModelBuildingRequest( Properties p )
079    {
080        ModelBuildingRequest config = new DefaultModelBuildingRequest();
081        if ( p != null )
082        {
083            config.setSystemProperties( p );
084        }
085        return config;
086    }
087
088    public void testDefaultBuildTimestampFormatShouldFormatTimeIn24HourFormat()
089    {
090        Calendar cal = Calendar.getInstance();
091        cal.setTimeZone(TimeZone.getTimeZone("UTC"));
092        cal.set( Calendar.HOUR, 12 );
093        cal.set( Calendar.AM_PM, Calendar.AM );
094
095        // just to make sure all the bases are covered...
096        cal.set( Calendar.HOUR_OF_DAY, 0 );
097        cal.set( Calendar.MINUTE, 16 );
098        cal.set( Calendar.SECOND, 0 );
099        cal.set( Calendar.YEAR, 1976 );
100        cal.set( Calendar.MONTH, Calendar.NOVEMBER );
101        cal.set( Calendar.DATE, 11 );
102
103        Date firstTestDate = cal.getTime();
104
105        cal.set( Calendar.HOUR, 11 );
106        cal.set( Calendar.AM_PM, Calendar.PM );
107
108        // just to make sure all the bases are covered...
109        cal.set( Calendar.HOUR_OF_DAY, 23 );
110
111        Date secondTestDate = cal.getTime();
112
113        SimpleDateFormat format =
114            new SimpleDateFormat( MavenBuildTimestamp.DEFAULT_BUILD_TIMESTAMP_FORMAT );
115        format.setTimeZone(TimeZone.getTimeZone("UTC"));
116        assertEquals( "1976-11-11T00:16:00Z", format.format( firstTestDate ) );
117        assertEquals( "1976-11-11T23:16:00Z", format.format( secondTestDate ) );
118    }
119
120    public void testDefaultBuildTimestampFormatWithLocalTimeZoneMidnightRollover()
121    {
122        Calendar cal = Calendar.getInstance();
123        cal.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
124
125        cal.set( Calendar.HOUR_OF_DAY, 1 );
126        cal.set( Calendar.MINUTE, 16 );
127        cal.set( Calendar.SECOND, 0 );
128        cal.set( Calendar.YEAR, 2014 );
129        cal.set( Calendar.MONTH, Calendar.JUNE );
130        cal.set( Calendar.DATE, 16 );
131
132        Date firstTestDate = cal.getTime();
133
134        cal.set( Calendar.MONTH, Calendar.NOVEMBER );
135
136        Date secondTestDate = cal.getTime();
137
138        SimpleDateFormat format =
139            new SimpleDateFormat( MavenBuildTimestamp.DEFAULT_BUILD_TIMESTAMP_FORMAT );
140        format.setTimeZone(TimeZone.getTimeZone("UTC"));
141        assertEquals( "2014-06-15T23:16:00Z", format.format( firstTestDate ) );
142        assertEquals( "2014-11-16T00:16:00Z", format.format( secondTestDate ) );
143    }
144
145    public void testShouldNotThrowExceptionOnReferenceToNonExistentValue()
146        throws Exception
147    {
148        Model model = new Model();
149
150        Scm scm = new Scm();
151        scm.setConnection( "${test}/somepath" );
152
153        model.setScm( scm );
154
155        ModelInterpolator interpolator = createInterpolator();
156
157        final SimpleProblemCollector collector = new SimpleProblemCollector();
158        Model out =
159            interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ), collector );
160
161        assertProblemFree(  collector );
162        assertEquals( "${test}/somepath", out.getScm().getConnection() );
163    }
164
165    public void testShouldThrowExceptionOnRecursiveScmConnectionReference()
166        throws Exception
167    {
168        Model model = new Model();
169
170        Scm scm = new Scm();
171        scm.setConnection( "${project.scm.connection}/somepath" );
172
173        model.setScm( scm );
174
175        try
176        {
177            ModelInterpolator interpolator = createInterpolator();
178
179            final SimpleProblemCollector collector = new SimpleProblemCollector();
180            interpolator.interpolateModel( model, null, createModelBuildingRequest( context ), collector );
181            assertColllectorState(  0, 1, 0, collector );
182        }
183        catch ( Exception e )
184        {
185
186        }
187    }
188
189    public void testShouldNotThrowExceptionOnReferenceToValueContainingNakedExpression()
190        throws Exception
191    {
192        Model model = new Model();
193
194        Scm scm = new Scm();
195        scm.setConnection( "${test}/somepath" );
196
197        model.setScm( scm );
198
199        model.addProperty( "test", "test" );
200
201        ModelInterpolator interpolator = createInterpolator();
202
203        final SimpleProblemCollector collector = new SimpleProblemCollector();
204        Model out =
205            interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ), collector );
206
207        assertProblemFree(  collector );
208
209        assertEquals( "test/somepath", out.getScm().getConnection() );
210    }
211
212    public void testShouldInterpolateOrganizationNameCorrectly()
213        throws Exception
214    {
215        String orgName = "MyCo";
216
217        Model model = new Model();
218        model.setName( "${pom.organization.name} Tools" );
219
220        Organization org = new Organization();
221        org.setName( orgName );
222
223        model.setOrganization( org );
224
225        ModelInterpolator interpolator = createInterpolator();
226
227        Model out =
228            interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ),
229                                           new SimpleProblemCollector() );
230
231        assertEquals( orgName + " Tools", out.getName() );
232    }
233
234    public void testShouldInterpolateDependencyVersionToSetSameAsProjectVersion()
235        throws Exception
236    {
237        Model model = new Model();
238        model.setVersion( "3.8.1" );
239
240        Dependency dep = new Dependency();
241        dep.setVersion( "${version}" );
242
243        model.addDependency( dep );
244
245        ModelInterpolator interpolator = createInterpolator();
246
247        final SimpleProblemCollector collector = new SimpleProblemCollector();
248        Model out =
249            interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ), collector );
250        assertColllectorState(0, 0, 1, collector );
251
252        assertEquals( "3.8.1", ( out.getDependencies().get( 0 ) ).getVersion() );
253    }
254
255    public void testShouldNotInterpolateDependencyVersionWithInvalidReference()
256        throws Exception
257    {
258        Model model = new Model();
259        model.setVersion( "3.8.1" );
260
261        Dependency dep = new Dependency();
262        dep.setVersion( "${something}" );
263
264        model.addDependency( dep );
265
266        /*
267         // This is the desired behaviour, however there are too many crappy poms in the repo and an issue with the
268         // timing of executing the interpolation
269
270         try
271         {
272         new RegexBasedModelInterpolator().interpolate( model, context );
273         fail( "Should have failed to interpolate with invalid reference" );
274         }
275         catch ( ModelInterpolationException expected )
276         {
277         assertTrue( true );
278         }
279         */
280
281        ModelInterpolator interpolator = createInterpolator();
282
283        final SimpleProblemCollector collector = new SimpleProblemCollector();
284        Model out =
285            interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ), collector );
286        assertProblemFree( collector );
287
288        assertEquals( "${something}", ( out.getDependencies().get( 0 ) ).getVersion() );
289    }
290
291    public void testTwoReferences()
292        throws Exception
293    {
294        Model model = new Model();
295        model.setVersion( "3.8.1" );
296        model.setArtifactId( "foo" );
297
298        Dependency dep = new Dependency();
299        dep.setVersion( "${artifactId}-${version}" );
300
301        model.addDependency( dep );
302
303        ModelInterpolator interpolator = createInterpolator();
304
305        final SimpleProblemCollector collector = new SimpleProblemCollector();
306        Model out =
307            interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ), collector );
308        assertColllectorState( 0, 0, 2, collector );
309
310        assertEquals( "foo-3.8.1", ( out.getDependencies().get( 0 ) ).getVersion() );
311    }
312
313    public void testBasedir()
314        throws Exception
315    {
316        Model model = new Model();
317        model.setVersion( "3.8.1" );
318        model.setArtifactId( "foo" );
319
320        Repository repository = new Repository();
321
322        repository.setUrl( "file://localhost/${basedir}/temp-repo" );
323
324        model.addRepository( repository );
325
326        ModelInterpolator interpolator = createInterpolator();
327
328        final SimpleProblemCollector collector = new SimpleProblemCollector();
329        Model out = interpolator.interpolateModel( model, null, createModelBuildingRequest( context ), collector );
330        assertProblemFree( collector );
331
332        assertEquals( "file://localhost/myBasedir/temp-repo", ( out.getRepositories().get( 0 ) ).getUrl() );
333    }
334
335    public void testBaseUri()
336        throws Exception
337    {
338        Model model = new Model();
339        model.setVersion( "3.8.1" );
340        model.setArtifactId( "foo" );
341
342        Repository repository = new Repository();
343
344        repository.setUrl( "${project.baseUri}/temp-repo" );
345
346        model.addRepository( repository );
347
348        ModelInterpolator interpolator = createInterpolator();
349
350        final SimpleProblemCollector collector = new SimpleProblemCollector();
351        Model out = interpolator.interpolateModel( model, null, createModelBuildingRequest( context ), collector );
352        assertProblemFree( collector );
353
354        assertEquals( "myBaseUri/temp-repo", ( out.getRepositories().get( 0 ) ).getUrl() );
355    }
356
357    public void testEnvars()
358        throws Exception
359    {
360         Properties context = new Properties();
361
362        context.put( "env.HOME", "/path/to/home" );
363
364        Model model = new Model();
365
366        Properties modelProperties = new Properties();
367
368        modelProperties.setProperty( "outputDirectory", "${env.HOME}" );
369
370        model.setProperties( modelProperties );
371
372        ModelInterpolator interpolator = createInterpolator();
373
374        final SimpleProblemCollector collector = new SimpleProblemCollector();
375        Model out =
376            interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ), collector );
377        assertProblemFree( collector );
378
379        assertEquals( "/path/to/home", out.getProperties().getProperty( "outputDirectory" ) );
380    }
381
382    public void testEnvarExpressionThatEvaluatesToNullReturnsTheLiteralString()
383        throws Exception
384    {
385        Model model = new Model();
386
387        Properties modelProperties = new Properties();
388
389        modelProperties.setProperty( "outputDirectory", "${env.DOES_NOT_EXIST}" );
390
391        model.setProperties( modelProperties );
392
393        ModelInterpolator interpolator = createInterpolator();
394
395        final SimpleProblemCollector collector = new SimpleProblemCollector();
396        Model out =
397            interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ), collector );
398        assertProblemFree( collector );
399
400        assertEquals( out.getProperties().getProperty( "outputDirectory" ), "${env.DOES_NOT_EXIST}" );
401    }
402
403    public void testExpressionThatEvaluatesToNullReturnsTheLiteralString()
404        throws Exception
405    {
406        Model model = new Model();
407
408        Properties modelProperties = new Properties();
409
410        modelProperties.setProperty( "outputDirectory", "${DOES_NOT_EXIST}" );
411
412        model.setProperties( modelProperties );
413
414        ModelInterpolator interpolator = createInterpolator();
415
416        final SimpleProblemCollector collector = new SimpleProblemCollector();
417        Model out =
418            interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ), collector );
419        assertProblemFree( collector );
420
421        assertEquals( out.getProperties().getProperty( "outputDirectory" ), "${DOES_NOT_EXIST}" );
422    }
423
424    public void testShouldInterpolateSourceDirectoryReferencedFromResourceDirectoryCorrectly()
425        throws Exception
426    {
427        Model model = new Model();
428
429        Build build = new Build();
430        build.setSourceDirectory( "correct" );
431
432        Resource res = new Resource();
433        res.setDirectory( "${project.build.sourceDirectory}" );
434
435        build.addResource( res );
436
437        Resource res2 = new Resource();
438        res2.setDirectory( "${pom.build.sourceDirectory}" );
439
440        build.addResource( res2 );
441
442        Resource res3 = new Resource();
443        res3.setDirectory( "${build.sourceDirectory}" );
444
445        build.addResource( res3 );
446
447        model.setBuild( build );
448
449        ModelInterpolator interpolator = createInterpolator();
450
451        final SimpleProblemCollector collector = new SimpleProblemCollector();
452        Model out = interpolator.interpolateModel( model, null, createModelBuildingRequest( context ), collector );
453        assertColllectorState( 0, 0, 2, collector );
454
455
456        List<Resource> outResources = out.getBuild().getResources();
457        Iterator<Resource> resIt = outResources.iterator();
458
459        assertEquals( build.getSourceDirectory(), resIt.next().getDirectory() );
460        assertEquals( build.getSourceDirectory(), resIt.next().getDirectory() );
461        assertEquals( build.getSourceDirectory(), resIt.next().getDirectory() );
462    }
463
464    public void testShouldInterpolateUnprefixedBasedirExpression()
465        throws Exception
466    {
467        File basedir = new File( "/test/path" );
468        Model model = new Model();
469        Dependency dep = new Dependency();
470        dep.setSystemPath( "${basedir}/artifact.jar" );
471
472        model.addDependency( dep );
473
474        ModelInterpolator interpolator = createInterpolator();
475
476        final SimpleProblemCollector collector = new SimpleProblemCollector();
477        Model result = interpolator.interpolateModel( model, basedir, createModelBuildingRequest( context ), collector );
478        assertProblemFree(  collector );
479
480
481        List<Dependency> rDeps = result.getDependencies();
482        assertNotNull( rDeps );
483        assertEquals( 1, rDeps.size() );
484        assertEquals( new File( basedir, "artifact.jar" ).getAbsolutePath(),
485                      new File( rDeps.get( 0 ).getSystemPath() ).getAbsolutePath() );
486    }
487
488    protected abstract ModelInterpolator createInterpolator( PathTranslator translator )
489        throws Exception;
490
491    protected abstract ModelInterpolator createInterpolator()
492        throws Exception;
493
494}