1   package org.apache.maven.project.interpolation;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.model.Build;
23  import org.apache.maven.model.Dependency;
24  import org.apache.maven.model.Model;
25  import org.apache.maven.model.Organization;
26  import org.apache.maven.model.Repository;
27  import org.apache.maven.model.Resource;
28  import org.apache.maven.model.Scm;
29  import org.apache.maven.project.DefaultProjectBuilderConfiguration;
30  import org.apache.maven.project.path.DefaultPathTranslator;
31  import org.apache.maven.project.path.PathTranslator;
32  import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
33  
34  import java.io.File;
35  import java.io.IOException;
36  import java.text.SimpleDateFormat;
37  import java.util.Calendar;
38  import java.util.Collections;
39  import java.util.Date;
40  import java.util.HashMap;
41  import java.util.Iterator;
42  import java.util.List;
43  import java.util.Map;
44  import java.util.Properties;
45  
46  import junit.framework.TestCase;
47  
48  /**
49   * @author jdcasey
50   * @version $Id: AbstractModelInterpolatorTest.java 769023 2009-04-27 15:08:43Z brett $
51   */
52  public abstract class AbstractModelInterpolatorTest
53      extends TestCase
54  {
55      private Map context;
56      
57      protected void setUp()
58          throws Exception
59      {
60          super.setUp();
61  
62          context = new HashMap();
63          context.put( "basedir", "myBasedir" );
64          context.put( "project.baseUri", "myBaseUri" );
65      }
66      
67      public void testDefaultBuildTimestampFormatShouldParseTimeIn24HourFormat()
68      {
69          Calendar cal = Calendar.getInstance();
70          cal.set( Calendar.HOUR, 12 );
71          cal.set( Calendar.AM_PM, Calendar.AM );
72          
73          // just to make sure all the bases are covered...
74          cal.set( Calendar.HOUR_OF_DAY, 0 );
75          cal.set( Calendar.MINUTE, 16 );
76          cal.set( Calendar.YEAR, 1976 );
77          cal.set( Calendar.MONTH, Calendar.NOVEMBER );
78          cal.set( Calendar.DATE, 11 );
79          
80          Date firstTestDate = cal.getTime();
81          
82          cal.set( Calendar.HOUR, 11 );
83          cal.set( Calendar.AM_PM, Calendar.PM );
84          
85          // just to make sure all the bases are covered...
86          cal.set( Calendar.HOUR_OF_DAY, 23 );
87          
88          Date secondTestDate = cal.getTime();
89          
90          SimpleDateFormat format = new SimpleDateFormat( ModelInterpolator.DEFAULT_BUILD_TIMESTAMP_FORMAT );
91          assertEquals( "19761111-0016", format.format( firstTestDate ) );
92          assertEquals( "19761111-2316", format.format( secondTestDate ) );
93      }
94  
95      public void testShouldNotThrowExceptionOnReferenceToNonExistentValue()
96          throws Exception
97      {
98          Model model = new Model();
99  
100         Scm scm = new Scm();
101         scm.setConnection( "${test}/somepath" );
102 
103         model.setScm( scm );
104 
105         ModelInterpolator interpolator = createInterpolator();
106         
107         Model out = interpolator.interpolate( model, context );
108 
109         assertEquals( "${test}/somepath", out.getScm().getConnection() );
110     }
111 
112     public void testShouldThrowExceptionOnRecursiveScmConnectionReference()
113         throws Exception
114     {
115         Model model = new Model();
116 
117         Scm scm = new Scm();
118         scm.setConnection( "${project.scm.connection}/somepath" );
119 
120         model.setScm( scm );
121 
122         try
123         {
124             ModelInterpolator interpolator = createInterpolator();
125             
126             interpolator.interpolate( model, context );
127 
128             fail( "The interpolator should not allow self-referencing expressions in POM." );
129         }
130         catch ( ModelInterpolationException e )
131         {
132 
133         }
134     }
135 
136     public void testShouldNotThrowExceptionOnReferenceToValueContainingNakedExpression()
137         throws Exception
138     {
139         Model model = new Model();
140 
141         Scm scm = new Scm();
142         scm.setConnection( "${test}/somepath" );
143 
144         model.setScm( scm );
145 
146         model.addProperty( "test", "test" );
147 
148         ModelInterpolator interpolator = createInterpolator();
149         
150         Model out = interpolator.interpolate( model, context );
151         
152         assertEquals( "test/somepath", out.getScm().getConnection() );
153     }
154 
155     public void testShouldInterpolateOrganizationNameCorrectly()
156         throws Exception
157     {
158         String orgName = "MyCo";
159 
160         Model model = new Model();
161         model.setName( "${pom.organization.name} Tools" );
162 
163         Organization org = new Organization();
164         org.setName( orgName );
165 
166         model.setOrganization( org );
167 
168         ModelInterpolator interpolator = createInterpolator();
169         
170         Model out = interpolator.interpolate( model, context );
171         
172         assertEquals( orgName + " Tools", out.getName() );
173     }
174 
175     public void testShouldInterpolateDependencyVersionToSetSameAsProjectVersion()
176         throws Exception
177     {
178         Model model = new Model();
179         model.setVersion( "3.8.1" );
180 
181         Dependency dep = new Dependency();
182         dep.setVersion( "${version}" );
183 
184         model.addDependency( dep );
185 
186         ModelInterpolator interpolator = createInterpolator();
187         
188         Model out = interpolator.interpolate( model, context );
189         
190         assertEquals( "3.8.1", ( (Dependency) out.getDependencies().get( 0 ) ).getVersion() );
191     }
192 
193     public void testShouldNotInterpolateDependencyVersionWithInvalidReference()
194         throws Exception
195     {
196         Model model = new Model();
197         model.setVersion( "3.8.1" );
198 
199         Dependency dep = new Dependency();
200         dep.setVersion( "${something}" );
201 
202         model.addDependency( dep );
203 
204         /*
205          // This is the desired behaviour, however there are too many crappy poms in the repo and an issue with the
206          // timing of executing the interpolation
207 
208          try
209          {
210          new RegexBasedModelInterpolator().interpolate( model, context );
211          fail( "Should have failed to interpolate with invalid reference" );
212          }
213          catch ( ModelInterpolationException expected )
214          {
215          assertTrue( true );
216          }
217          */
218 
219         ModelInterpolator interpolator = createInterpolator();
220         
221         Model out = interpolator.interpolate( model, context );
222         
223         assertEquals( "${something}", ( (Dependency) out.getDependencies().get( 0 ) ).getVersion() );
224     }
225 
226     public void testTwoReferences()
227         throws Exception
228     {
229         Model model = new Model();
230         model.setVersion( "3.8.1" );
231         model.setArtifactId( "foo" );
232 
233         Dependency dep = new Dependency();
234         dep.setVersion( "${artifactId}-${version}" );
235 
236         model.addDependency( dep );
237 
238         ModelInterpolator interpolator = createInterpolator();
239         
240         Model out = interpolator.interpolate( model, context );
241         
242         assertEquals( "foo-3.8.1", ( (Dependency) out.getDependencies().get( 0 ) ).getVersion() );
243     }
244 
245     public void testBasedir()
246         throws Exception
247     {
248         Model model = new Model();
249         model.setVersion( "3.8.1" );
250         model.setArtifactId( "foo" );
251 
252         Repository repository = new Repository();
253 
254         repository.setUrl( "file://localhost/${basedir}/temp-repo" );
255 
256         model.addRepository( repository );
257 
258         ModelInterpolator interpolator = createInterpolator();
259         
260         Model out = interpolator.interpolate( model, context );
261         
262         assertEquals( "file://localhost/myBasedir/temp-repo", ( (Repository) out.getRepositories().get( 0 ) ).getUrl() );
263     }
264 
265     public void testBaseUri()
266         throws Exception
267     {
268         Model model = new Model();
269         model.setVersion( "3.8.1" );
270         model.setArtifactId( "foo" );
271 
272         Repository repository = new Repository();
273 
274         repository.setUrl( "${project.baseUri}/temp-repo" );
275 
276         model.addRepository( repository );
277 
278         ModelInterpolator interpolator = createInterpolator();
279 
280         Model out = interpolator.interpolate( model, context );
281 
282         assertEquals( "myBaseUri/temp-repo", ( (Repository) out.getRepositories().get( 0 ) ).getUrl() );
283     }
284 
285     public void testEnvars()
286         throws Exception
287     {
288         Map context = new HashMap();
289 
290         context.put( "env.HOME", "/path/to/home" );
291 
292         Model model = new Model();
293 
294         Properties modelProperties = new Properties();
295 
296         modelProperties.setProperty( "outputDirectory", "${env.HOME}" );
297 
298         model.setProperties( modelProperties );
299 
300         ModelInterpolator interpolator = createInterpolator();
301         
302         Model out = interpolator.interpolate( model, context );
303         
304         assertEquals( "/path/to/home", out.getProperties().getProperty( "outputDirectory" ) );
305     }
306 
307     public void testEnvarExpressionThatEvaluatesToNullReturnsTheLiteralString()
308         throws Exception
309     {
310         Properties envars = new Properties();
311 
312         Model model = new Model();
313 
314         Properties modelProperties = new Properties();
315 
316         modelProperties.setProperty( "outputDirectory", "${env.DOES_NOT_EXIST}" );
317 
318         model.setProperties( modelProperties );
319 
320         ModelInterpolator interpolator = createInterpolator();
321         
322         Model out = interpolator.interpolate( model, context );
323 
324         assertEquals( out.getProperties().getProperty( "outputDirectory" ), "${env.DOES_NOT_EXIST}" );
325     }
326 
327     public void testExpressionThatEvaluatesToNullReturnsTheLiteralString()
328         throws Exception
329     {
330         Model model = new Model();
331 
332         Properties modelProperties = new Properties();
333 
334         modelProperties.setProperty( "outputDirectory", "${DOES_NOT_EXIST}" );
335 
336         model.setProperties( modelProperties );
337 
338         ModelInterpolator interpolator = createInterpolator();
339         
340         Model out = interpolator.interpolate( model, context );
341         
342         assertEquals( out.getProperties().getProperty( "outputDirectory" ), "${DOES_NOT_EXIST}" );
343     }
344 
345     public void testShouldInterpolateSourceDirectoryReferencedFromResourceDirectoryCorrectly()
346         throws Exception
347     {
348         Model model = new Model();
349 
350         Build build = new Build();
351         build.setSourceDirectory( "correct" );
352 
353         Resource res = new Resource();
354         res.setDirectory( "${project.build.sourceDirectory}" );
355 
356         build.addResource( res );
357 
358         Resource res2 = new Resource();
359         res2.setDirectory( "${pom.build.sourceDirectory}" );
360 
361         build.addResource( res2 );
362 
363         Resource res3 = new Resource();
364         res3.setDirectory( "${build.sourceDirectory}" );
365 
366         build.addResource( res3 );
367 
368         model.setBuild( build );
369 
370         ModelInterpolator interpolator = createInterpolator();
371         
372         Model out = interpolator.interpolate( model, context );
373         
374         List outResources = out.getBuild().getResources();
375         Iterator resIt = outResources.iterator();
376 
377         assertEquals( build.getSourceDirectory(), ( (Resource) resIt.next() ).getDirectory() );
378         assertEquals( build.getSourceDirectory(), ( (Resource) resIt.next() ).getDirectory() );
379         assertEquals( build.getSourceDirectory(), ( (Resource) resIt.next() ).getDirectory() );
380     }
381 
382     public void testShouldInterpolateUnprefixedBasedirExpression()
383         throws Exception
384     {
385         File basedir = new File( "/test/path" );
386         Model model = new Model();
387         Dependency dep = new Dependency();
388         dep.setSystemPath( "${basedir}/artifact.jar" );
389 
390         model.addDependency( dep );
391 
392         ModelInterpolator interpolator = createInterpolator();
393         
394         Model result = interpolator.interpolate( model, basedir, new DefaultProjectBuilderConfiguration(), true );
395 
396         List rDeps = result.getDependencies();
397         assertNotNull( rDeps );
398         assertEquals( 1, rDeps.size() );
399         assertEquals( new File( basedir, "artifact.jar" ).getAbsolutePath(), new File( ( (Dependency) rDeps.get( 0 ) )
400             .getSystemPath() ).getAbsolutePath() );
401     }
402     
403     public void testTwoLevelRecursiveBasedirAlignedExpression()
404         throws Exception
405     {
406         Model model = new Model();
407         Build build = new Build();
408         
409         model.setBuild( build );
410         
411         build.setDirectory( "${project.basedir}/target" );
412         build.setOutputDirectory( "${project.build.directory}/classes" );
413         
414         PathTranslator translator = new DefaultPathTranslator();
415         ModelInterpolator interpolator = createInterpolator( translator );
416         
417         File basedir = new File( System.getProperty( "java.io.tmpdir" ), "base" );
418         
419         String value = interpolator.interpolate( "${project.build.outputDirectory}/foo", model, basedir, new DefaultProjectBuilderConfiguration(), true );
420         value = value.replace( '/', File.separatorChar ).replace( '\\', File.separatorChar );
421         
422         String check = new File( basedir, "target/classes/foo" ).getAbsolutePath();
423         check = check.replace( '/', File.separatorChar ).replace( '\\', File.separatorChar );
424         
425         assertEquals( check, value );
426     }
427 
428     protected abstract ModelInterpolator createInterpolator( PathTranslator translator )
429         throws Exception;
430 
431     protected abstract ModelInterpolator createInterpolator()
432         throws Exception;
433 
434 //    public void testPOMExpressionDoesNotUseSystemProperty()
435 //        throws Exception
436 //    {
437 //        Model model = new Model();
438 //        model.setVersion( "1.0" );
439 //
440 //        Properties modelProperties = new Properties();
441 //        modelProperties.setProperty( "version", "prop version" );
442 //        modelProperties.setProperty( "foo.version", "prop foo.version" );
443 //        modelProperties.setProperty( "pom.version", "prop pom.version" );
444 //        modelProperties.setProperty( "project.version", "prop project.version" );
445 //
446 //        model.setProperties( modelProperties );
447 //
448 //        Dependency dep = new Dependency();
449 //        model.addDependency( dep );
450 //
451 //        checkDep( "prop version", "${version}", model );
452 //        checkDep( "1.0", "${pom.version}", model );
453 //        checkDep( "1.0", "${project.version}", model );
454 //        checkDep( "prop foo.version", "${foo.version}", model );
455 //    }
456 //
457 //    private void checkDep( String expectedVersion,
458 //                           String depVersionExpr,
459 //                           Model model )
460 //        throws Exception
461 //    {
462 //        ( (Dependency) model.getDependencies().get( 0 ) ).setVersion( depVersionExpr );
463 //        Model out = createInterpolator().interpolate( model, context );
464 //        String result = ( (Dependency) out.getDependencies().get( 0 ) ).getVersion();
465 //        assertEquals( "Expected '" + expectedVersion + "' for version expression '"
466 //                      + depVersionExpr + "', but was '" + result + "'", expectedVersion, result );
467 //    }
468 
469 }