View Javadoc
1   package org.apache.maven.archiver;
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 junit.framework.TestCase;
23  import org.apache.maven.artifact.Artifact;
24  import org.apache.maven.artifact.DependencyResolutionRequiredException;
25  import org.apache.maven.artifact.handler.ArtifactHandler;
26  import org.apache.maven.artifact.handler.DefaultArtifactHandler;
27  import org.apache.maven.artifact.repository.ArtifactRepository;
28  import org.apache.maven.execution.MavenSession;
29  import org.apache.maven.execution.ReactorManager;
30  import org.apache.maven.model.Build;
31  import org.apache.maven.model.Model;
32  import org.apache.maven.model.Organization;
33  import org.apache.maven.monitor.event.EventDispatcher;
34  import org.apache.maven.project.MavenProject;
35  import org.apache.maven.settings.Settings;
36  import org.codehaus.plexus.PlexusContainer;
37  import org.codehaus.plexus.archiver.jar.JarArchiver;
38  import org.codehaus.plexus.archiver.jar.ManifestException;
39  import org.apache.maven.shared.utils.io.FileUtils;
40  import org.apache.maven.shared.utils.StringUtils;
41  
42  import java.io.File;
43  import java.io.IOException;
44  import java.net.URI;
45  import java.net.URL;
46  import java.util.ArrayList;
47  import java.util.Collections;
48  import java.util.Comparator;
49  import java.util.Date;
50  import java.util.HashMap;
51  import java.util.List;
52  import java.util.Map;
53  import java.util.Properties;
54  import java.util.Set;
55  import java.util.TreeSet;
56  import java.util.jar.Attributes;
57  import java.util.jar.JarFile;
58  import java.util.jar.Manifest;
59  
60  public class MavenArchiverTest
61      extends TestCase
62  {
63      static class ArtifactComparator
64          implements Comparator<Artifact>
65      {
66          public int compare( Artifact o1, Artifact o2 )
67          {
68              return o1.getArtifactId().compareTo( o2.getArtifactId() );
69          }
70  
71          public boolean equals( Object o )
72          {
73              return false;
74          }
75      }
76  
77      public void testGetManifestExtensionList()
78          throws Exception
79      {
80          MavenArchiver archiver = new MavenArchiver();
81  
82          MavenSession session = getDummySession();
83  
84          Model model = new Model();
85          model.setArtifactId( "dummy" );
86  
87          MavenProject project = new MavenProject( model );
88          // we need to sort the artifacts for test purposes
89          Set<Artifact> artifacts = new TreeSet<Artifact>( new ArtifactComparator() );
90          project.setArtifacts( artifacts );
91  
92          // there should be a mock or a setter for this field.
93          ManifestConfiguration config = new ManifestConfiguration()
94          {
95              public boolean isAddExtensions()
96              {
97                  return true;
98              }
99          };
100 
101         Manifest manifest;
102 
103         manifest = archiver.getManifest( session, project, config );
104 
105         assertNotNull( manifest.getMainAttributes() );
106 
107         for ( Map.Entry<String, Attributes> entry : manifest.getEntries().entrySet() )
108         {
109             System.out.println( entry.getKey() + " " + entry.getValue().getValue( "Extension-List" ) );
110 
111         }
112 
113         assertEquals( null, manifest.getMainAttributes().getValue( "Extension-List" ) );
114 
115         MockArtifact artifact1 = new MockArtifact();
116         artifact1.setGroupId( "org.apache.dummy" );
117         artifact1.setArtifactId( "dummy1" );
118         artifact1.setVersion( "1.0" );
119         artifact1.setType( "dll" );
120         artifact1.setScope( "compile" );
121 
122         artifacts.add( artifact1 );
123 
124         manifest = archiver.getManifest( session, project, config );
125 
126         assertEquals( null, manifest.getMainAttributes().getValue( "Extension-List" ) );
127 
128         MockArtifact artifact2 = new MockArtifact();
129         artifact2.setGroupId( "org.apache.dummy" );
130         artifact2.setArtifactId( "dummy2" );
131         artifact2.setVersion( "1.0" );
132         artifact2.setType( "jar" );
133         artifact2.setScope( "compile" );
134 
135         artifacts.add( artifact2 );
136 
137         manifest = archiver.getManifest( session, project, config );
138 
139         assertEquals( "dummy2", manifest.getMainAttributes().getValue( "Extension-List" ) );
140 
141         MockArtifact artifact3 = new MockArtifact();
142         artifact3.setGroupId( "org.apache.dummy" );
143         artifact3.setArtifactId( "dummy3" );
144         artifact3.setVersion( "1.0" );
145         artifact3.setScope( "test" );
146         artifact3.setType( "jar" );
147 
148         artifacts.add( artifact3 );
149 
150         manifest = archiver.getManifest( session, project, config );
151 
152         assertEquals( "dummy2", manifest.getMainAttributes().getValue( "Extension-List" ) );
153 
154         MockArtifact artifact4 = new MockArtifact();
155         artifact4.setGroupId( "org.apache.dummy" );
156         artifact4.setArtifactId( "dummy4" );
157         artifact4.setVersion( "1.0" );
158         artifact4.setType( "jar" );
159         artifact4.setScope( "compile" );
160 
161         artifacts.add( artifact4 );
162 
163         manifest = archiver.getManifest( session, project, config );
164 
165         assertEquals( "dummy2 dummy4", manifest.getMainAttributes().getValue( "Extension-List" ) );
166     }
167 
168     public void testMultiClassPath()
169         throws Exception
170     {
171         final File tempFile = File.createTempFile( "maven-archiver-test-", ".jar" );
172 
173         try
174         {
175             MavenArchiver archiver = new MavenArchiver();
176 
177             MavenSession session = getDummySession();
178 
179             Model model = new Model();
180             model.setArtifactId( "dummy" );
181 
182             MavenProject project = new MavenProject( model )
183             {
184                 public List<String> getRuntimeClasspathElements()
185                 {
186                     return Collections.singletonList( tempFile.getAbsolutePath() );
187                 }
188             };
189 
190             // there should be a mock or a setter for this field.
191             ManifestConfiguration manifestConfig = new ManifestConfiguration()
192             {
193                 public boolean isAddClasspath()
194                 {
195                     return true;
196                 }
197             };
198 
199             MavenArchiveConfiguration archiveConfiguration = new MavenArchiveConfiguration();
200             archiveConfiguration.setManifest( manifestConfig );
201             archiveConfiguration.addManifestEntry( "Class-Path", "help/" );
202 
203             Manifest manifest = archiver.getManifest( session, project, archiveConfiguration );
204             String classPath = manifest.getMainAttributes().getValue( "Class-Path" );
205             assertTrue( "User specified Class-Path entry was not added to manifest", classPath.contains( "help/" ) );
206             assertTrue( "Class-Path generated by addClasspath was not added to manifest",
207                         classPath.contains( tempFile.getName() ) );
208         }
209         finally
210         {
211             //noinspection ResultOfMethodCallIgnored
212             tempFile.delete();
213         }
214     }
215 
216     public void testRecreation()
217         throws Exception
218     {
219         File jarFile = new File( "target/test/dummy.jar" );
220         JarArchiver jarArchiver = getCleanJarArciver( jarFile );
221 
222         MavenArchiver archiver = getMavenArchiver( jarArchiver );
223 
224         MavenSession session = getDummySession();
225         MavenProject project = getDummyProject();
226 
227         MavenArchiveConfiguration config = new MavenArchiveConfiguration();
228         config.setForced( false );
229 
230         FileUtils.deleteDirectory( "target/maven-archiver" );
231         archiver.createArchive( session, project, config );
232         assertTrue( jarFile.exists() );
233         jarFile.setLastModified( System.currentTimeMillis() - 60000L );
234         long time = jarFile.lastModified();
235 
236         List<File> files = FileUtils.getFiles( new File( "target/maven-archiver" ), "**/**", null, true );
237         for ( Object file : files )
238         {
239             File f = (File) file;
240             f.setLastModified( time );
241         }
242 
243         archiver.createArchive( session, project, config );
244         assertEquals( jarFile.lastModified(), time );
245 
246         config.setForced( true );
247         archiver.createArchive( session, project, config );
248         assertTrue( jarFile.lastModified() > time );
249     }
250 
251     public void testNotGenerateImplementationVersionForMANIFESTMF()
252         throws Exception
253     {
254         JarFile jar = null;
255         try
256         {
257             File jarFile = new File( "target/test/dummy.jar" );
258             JarArchiver jarArchiver = getCleanJarArciver( jarFile );
259 
260             MavenArchiver archiver = getMavenArchiver( jarArchiver );
261 
262             MavenSession session = getDummySession();
263             MavenProject project = getDummyProject();
264 
265             MavenArchiveConfiguration config = new MavenArchiveConfiguration();
266             config.setForced( true );
267             config.getManifest().setAddDefaultImplementationEntries( false );
268             archiver.createArchive( session, project, config );
269             assertTrue( jarFile.exists() );
270 
271             jar = new JarFile( jarFile );
272             Map<Object, Object> entries = jar.getManifest().getMainAttributes();
273             assertFalse( entries.containsKey( Attributes.Name.IMPLEMENTATION_VERSION ) ); // "Implementation-Version"
274         }
275         finally
276         {
277             // cleanup streams
278             if ( jar != null )
279             {
280                 jar.close();
281             }
282         }
283     }
284 
285     public void testGenerateImplementationVersionForMANIFESTMF()
286         throws Exception
287     {
288         JarFile jar = null;
289         try
290         {
291             File jarFile = new File( "target/test/dummy.jar" );
292             JarArchiver jarArchiver = getCleanJarArciver( jarFile );
293 
294             MavenArchiver archiver = getMavenArchiver( jarArchiver );
295 
296             MavenSession session = getDummySession();
297             MavenProject project = getDummyProject();
298 
299             String ls = System.getProperty( "line.separator" );
300             project.setDescription( "foo " + ls + " bar " );
301             MavenArchiveConfiguration config = new MavenArchiveConfiguration();
302             config.setForced( true );
303             config.getManifest().setAddDefaultImplementationEntries( true );
304             config.addManifestEntry( "Description", project.getDescription() );
305             archiver.createArchive( session, project, config );
306             assertTrue( jarFile.exists() );
307 
308             jar = new JarFile( jarFile );
309 
310             Map<Object, Object> entries = jar.getManifest().getMainAttributes();
311 
312             assertTrue( entries.containsKey( Attributes.Name.IMPLEMENTATION_VERSION ) );
313             assertEquals( "0.1", entries.get( Attributes.Name.IMPLEMENTATION_VERSION ) );
314         }
315         finally
316         {
317             // cleanup streams
318             if ( jar != null )
319             {
320                 jar.close();
321             }
322         }
323     }
324 
325     private MavenArchiver getMavenArchiver( JarArchiver jarArchiver )
326     {
327         MavenArchiver archiver = new MavenArchiver();
328         archiver.setArchiver( jarArchiver );
329         archiver.setOutputFile( jarArchiver.getDestFile() );
330         return archiver;
331     }
332 
333     public void testDashesInClassPath_MSHARED_134()
334         throws IOException, ManifestException, DependencyResolutionRequiredException
335     {
336         File jarFile = new File( "target/test/dummyWithDashes.jar" );
337         JarArchiver jarArchiver = getCleanJarArciver( jarFile );
338 
339         MavenArchiver archiver = getMavenArchiver( jarArchiver );
340 
341         MavenSession session = getDummySession();
342         MavenProject project = getDummyProject();
343 
344         Set<Artifact> artifacts =
345             getArtifacts( getMockArtifact1(), getArtifactWithDot(), getMockArtifact2(), getMockArtifact3() );
346 
347         project.setArtifacts( artifacts );
348 
349         MavenArchiveConfiguration config = new MavenArchiveConfiguration();
350         config.setForced( false );
351 
352         final ManifestConfiguration mftConfig = config.getManifest();
353         mftConfig.setMainClass( "org.apache.maven.Foo" );
354         mftConfig.setAddClasspath( true );
355         mftConfig.setAddExtensions( true );
356         mftConfig.setClasspathPrefix( "./lib/" );
357 
358         archiver.createArchive( session, project, config );
359         assertTrue( jarFile.exists() );
360     }
361 
362     public void testDashesInClassPath_MSHARED_182()
363         throws IOException, ManifestException, DependencyResolutionRequiredException
364     {
365         File jarFile = new File( "target/test/dummy.jar" );
366         JarArchiver jarArchiver = getCleanJarArciver( jarFile );
367         MavenArchiver archiver = getMavenArchiver( jarArchiver );
368 
369         MavenSession session = getDummySession();
370         MavenProject project = getDummyProject();
371 
372         Set<Artifact> artifacts =
373             getArtifacts( getMockArtifact1(), getArtifactWithDot(), getMockArtifact2(), getMockArtifact3() );
374 
375         project.setArtifacts( artifacts );
376 
377         MavenArchiveConfiguration config = new MavenArchiveConfiguration();
378         config.setForced( false );
379 
380         final ManifestConfiguration mftConfig = config.getManifest();
381         mftConfig.setMainClass( "org.apache.maven.Foo" );
382         mftConfig.setAddClasspath( true );
383         mftConfig.setAddExtensions( true );
384         mftConfig.setClasspathPrefix( "./lib/" );
385         config.addManifestEntry( "Key1", "value1" );
386         config.addManifestEntry( "key2", "value2" );
387 
388         archiver.createArchive( session, project, config );
389         assertTrue( jarFile.exists() );
390         final Attributes mainAttributes = getJarFileManifest( jarFile ).getMainAttributes();
391         assertEquals( "value1", mainAttributes.getValue( "Key1" ) );
392         assertEquals( "value2", mainAttributes.getValue( "Key2" ) );
393     }
394 
395     public void testCarriageReturnInManifestEntry()
396         throws Exception
397     {
398         File jarFile = new File( "target/test/dummy.jar" );
399         JarArchiver jarArchiver = getCleanJarArciver( jarFile );
400 
401         MavenArchiver archiver = getMavenArchiver( jarArchiver );
402 
403         MavenSession session = getDummySession();
404         MavenProject project = getDummyProject();
405 
406         String ls = System.getProperty( "line.separator" );
407         project.setDescription( "foo " + ls + " bar " );
408         MavenArchiveConfiguration config = new MavenArchiveConfiguration();
409         config.setForced( true );
410         config.getManifest().setAddDefaultImplementationEntries( true );
411         config.addManifestEntry( "Description", project.getDescription() );
412         // config.addManifestEntry( "EntryWithTab", " foo tab " + ( '\u0009' ) + ( '\u0009' ) + " bar tab" + (
413         // '\u0009' ) );
414         archiver.createArchive( session, project, config );
415         assertTrue( jarFile.exists() );
416 
417         final Manifest manifest = getJarFileManifest( jarFile );
418         Attributes attributes = manifest.getMainAttributes();
419         assertTrue( project.getDescription().indexOf( ls ) > 0 );
420         Attributes.Name description = new Attributes.Name( "Description" );
421         String value = attributes.getValue( description );
422         assertNotNull( value );
423         assertFalse( value.indexOf( ls ) > 0 );
424     }
425 
426     public void testDeprecatedCreateArchiveAPI()
427         throws Exception
428     {
429         File jarFile = new File( "target/test/dummy.jar" );
430         JarArchiver jarArchiver = getCleanJarArciver( jarFile );
431 
432         MavenArchiver archiver = getMavenArchiver( jarArchiver );
433 
434         MavenProject project = getDummyProject();
435         MavenArchiveConfiguration config = new MavenArchiveConfiguration();
436         config.setForced( true );
437         config.getManifest().setAddDefaultImplementationEntries( true );
438         config.getManifest().setAddDefaultSpecificationEntries( true );
439 
440         //noinspection deprecation
441         MavenSession session = getDummySessionWithoutMavenVersion();
442         archiver.createArchive( session, project, config );
443         assertTrue( jarFile.exists() );
444         Attributes manifest = getJarFileManifest( jarFile ).getMainAttributes();
445 
446         assertEquals( "Apache Maven", manifest.get( new Attributes.Name( "Created-By" ) ) ); // no version number
447 
448         assertEquals( "archiver test", manifest.get( Attributes.Name.SPECIFICATION_TITLE ) );
449         assertEquals( "0.1", manifest.get( Attributes.Name.SPECIFICATION_VERSION ) );
450         assertEquals( "Apache", manifest.get( Attributes.Name.SPECIFICATION_VENDOR ) );
451 
452         assertEquals( "archiver test", manifest.get( Attributes.Name.IMPLEMENTATION_TITLE ) );
453         assertEquals( "0.1", manifest.get( Attributes.Name.IMPLEMENTATION_VERSION ) );
454         assertEquals( "org.apache.dummy", manifest.get( Attributes.Name.IMPLEMENTATION_VENDOR_ID ) );
455         assertEquals( "Apache", manifest.get( Attributes.Name.IMPLEMENTATION_VENDOR ) );
456         assertEquals( "http://maven.apache.org", manifest.get( Attributes.Name.IMPLEMENTATION_URL ) );
457 
458         assertEquals( System.getProperty( "java.version" ), manifest.get( new Attributes.Name( "Build-Jdk" ) ) );
459         assertEquals( System.getProperty( "user.name" ), manifest.get( new Attributes.Name( "Built-By" ) ) );
460     }
461 
462     public void testManifestEntries()
463         throws Exception
464     {
465         File jarFile = new File( "target/test/dummy.jar" );
466         JarArchiver jarArchiver = getCleanJarArciver( jarFile );
467 
468         MavenArchiver archiver = getMavenArchiver( jarArchiver );
469 
470         MavenSession session = getDummySession();
471         MavenProject project = getDummyProject();
472         MavenArchiveConfiguration config = new MavenArchiveConfiguration();
473         config.setForced( true );
474         config.getManifest().setAddDefaultImplementationEntries( true );
475         config.getManifest().setAddDefaultSpecificationEntries( true );
476 
477         Map<String, String> manifestEntries = new HashMap<String, String>();
478         manifestEntries.put( "foo", "bar" );
479         manifestEntries.put( "first-name", "olivier" );
480         manifestEntries.put( "keyWithEmptyValue", null );
481         config.setManifestEntries( manifestEntries );
482 
483         ManifestSection manifestSection = new ManifestSection();
484         manifestSection.setName( "UserSection" );
485         manifestSection.addManifestEntry( "key", "value" );
486         List<ManifestSection> manifestSections = new ArrayList<ManifestSection>();
487         manifestSections.add( manifestSection );
488         config.setManifestSections( manifestSections );
489         config.getManifest().setMainClass( "org.apache.maven.Foo" );
490         archiver.createArchive( session, project, config );
491         assertTrue( jarFile.exists() );
492 
493         final Manifest jarFileManifest = getJarFileManifest( jarFile );
494         Attributes manifest = jarFileManifest.getMainAttributes();
495 
496         assertEquals( "Apache Maven 3.0.4", manifest.get( new Attributes.Name( "Created-By" ) ) );
497 
498         assertEquals( "archiver test", manifest.get( Attributes.Name.SPECIFICATION_TITLE ) );
499         assertEquals( "0.1", manifest.get( Attributes.Name.SPECIFICATION_VERSION ) );
500         assertEquals( "Apache", manifest.get( Attributes.Name.SPECIFICATION_VENDOR ) );
501 
502         assertEquals( "archiver test", manifest.get( Attributes.Name.IMPLEMENTATION_TITLE ) );
503         assertEquals( "0.1", manifest.get( Attributes.Name.IMPLEMENTATION_VERSION ) );
504         assertEquals( "org.apache.dummy", manifest.get( Attributes.Name.IMPLEMENTATION_VENDOR_ID ) );
505         assertEquals( "Apache", manifest.get( Attributes.Name.IMPLEMENTATION_VENDOR ) );
506         assertEquals( "http://maven.apache.org", manifest.get( Attributes.Name.IMPLEMENTATION_URL ) );
507 
508         assertEquals( "org.apache.maven.Foo", manifest.get( Attributes.Name.MAIN_CLASS ) );
509 
510         assertEquals( "bar", manifest.get( new Attributes.Name( "foo" ) ) );
511         assertEquals( "olivier", manifest.get( new Attributes.Name( "first-name" ) ) );
512 
513         assertEquals( System.getProperty( "java.version" ), manifest.get( new Attributes.Name( "Build-Jdk" ) ) );
514         assertEquals( System.getProperty( "user.name" ), manifest.get( new Attributes.Name( "Built-By" ) ) );
515 
516         assertTrue( StringUtils.isEmpty( manifest.getValue( new Attributes.Name( "keyWithEmptyValue" ) ) ) );
517         assertTrue( manifest.containsKey( new Attributes.Name( "keyWithEmptyValue" ) ) );
518 
519         manifest = jarFileManifest.getAttributes( "UserSection" );
520 
521         assertEquals( "value", manifest.get( new Attributes.Name( "key" ) ) );
522     }
523 
524     public void testCreatedByManifestEntryWithoutMavenVersion()
525         throws Exception
526     {
527         File jarFile = new File( "target/test/dummy.jar" );
528         JarArchiver jarArchiver = getCleanJarArciver( jarFile );
529 
530         MavenArchiver archiver = getMavenArchiver( jarArchiver );
531 
532         MavenSession session = getDummySessionWithoutMavenVersion();
533         MavenProject project = getDummyProject();
534 
535         MavenArchiveConfiguration config = new MavenArchiveConfiguration();
536         config.setForced( true );
537 
538         archiver.createArchive( session, project, config );
539         assertTrue( jarFile.exists() );
540 
541         final Manifest manifest = getJarFileManifest( jarFile );
542         Map<Object, Object> entries = manifest.getMainAttributes();
543 
544         assertEquals( "Apache Maven", entries.get( new Attributes.Name( "Created-By" ) ) );
545     }
546 
547     /*
548      * Test to make sure that manifest sections are present in the manifest prior to the archive has been created.
549      */
550     public void testManifestSections()
551         throws Exception
552     {
553         MavenArchiver archiver = new MavenArchiver();
554 
555         MavenSession session = getDummySession();
556 
557         MavenProject project = getDummyProject();
558         MavenArchiveConfiguration config = new MavenArchiveConfiguration();
559 
560         ManifestSection manifestSection = new ManifestSection();
561         manifestSection.setName( "SectionOne" );
562         manifestSection.addManifestEntry( "key", "value" );
563         List<ManifestSection> manifestSections = new ArrayList<ManifestSection>();
564         manifestSections.add( manifestSection );
565         config.setManifestSections( manifestSections );
566 
567         Manifest manifest = archiver.getManifest( session, project, config );
568 
569         Attributes section = manifest.getAttributes( "SectionOne" );
570         assertNotNull( "The section is not present in the manifest as it should be.", section );
571 
572         String attribute = section.getValue( "key" );
573         assertNotNull( "The attribute we are looking for is not present in the section.", attribute );
574         assertEquals( "The value of the attribute is wrong.", "value", attribute );
575     }
576 
577     public void testDefaultClassPathValue()
578         throws Exception
579     {
580         MavenSession session = getDummySession();
581         MavenProject project = getDummyProject();
582         File jarFile = new File( "target/test/dummy.jar" );
583         JarArchiver jarArchiver = getCleanJarArciver( jarFile );
584 
585         MavenArchiver archiver = getMavenArchiver( jarArchiver );
586 
587         MavenArchiveConfiguration config = new MavenArchiveConfiguration();
588         config.setForced( true );
589         config.getManifest().setAddDefaultImplementationEntries( true );
590         config.getManifest().setAddDefaultSpecificationEntries( true );
591         config.getManifest().setMainClass( "org.apache.maven.Foo" );
592         config.getManifest().setAddClasspath( true );
593         archiver.createArchive( session, project, config );
594         assertTrue( jarFile.exists() );
595         final Manifest manifest = getJarFileManifest( jarFile );
596         String classPath = manifest.getMainAttributes().getValue( Attributes.Name.CLASS_PATH );
597         assertNotNull( classPath );
598         String[] classPathEntries = StringUtils.split( classPath, " " );
599         assertEquals( "dummy1-1.0.jar", classPathEntries[0] );
600         assertEquals( "dummy2-1.5.jar", classPathEntries[1] );
601         assertEquals( "dummy3-2.0.jar", classPathEntries[2] );
602     }
603 
604     private void deleteAndAssertNotPresent( File jarFile )
605     {
606         jarFile.delete();
607         assertFalse( jarFile.exists() );
608     }
609 
610     public void testDefaultClassPathValue_WithSnapshot()
611         throws Exception
612     {
613         MavenSession session = getDummySession();
614         MavenProject project = getDummyProjectWithSnapshot();
615         File jarFile = new File( "target/test/dummy.jar" );
616         JarArchiver jarArchiver = getCleanJarArciver( jarFile );
617 
618         MavenArchiver archiver = getMavenArchiver( jarArchiver );
619 
620         MavenArchiveConfiguration config = new MavenArchiveConfiguration();
621         config.setForced( true );
622         config.getManifest().setAddDefaultImplementationEntries( true );
623         config.getManifest().setAddDefaultSpecificationEntries( true );
624         config.getManifest().setMainClass( "org.apache.maven.Foo" );
625         config.getManifest().setAddClasspath( true );
626         archiver.createArchive( session, project, config );
627         assertTrue( jarFile.exists() );
628 
629         final Manifest manifest = getJarFileManifest( jarFile );
630         String classPath = manifest.getMainAttributes().getValue( Attributes.Name.CLASS_PATH );
631         assertNotNull( classPath );
632         String[] classPathEntries = StringUtils.split( classPath, " " );
633         assertEquals( "dummy1-1.1-20081022.112233-1.jar", classPathEntries[0] );
634         assertEquals( "dummy2-1.5.jar", classPathEntries[1] );
635         assertEquals( "dummy3-2.0.jar", classPathEntries[2] );
636     }
637 
638     public void testMavenRepoClassPathValue()
639         throws Exception
640     {
641         MavenSession session = getDummySession();
642         MavenProject project = getDummyProject();
643         File jarFile = new File( "target/test/dummy.jar" );
644         JarArchiver jarArchiver = getCleanJarArciver( jarFile );
645 
646         MavenArchiver archiver = getMavenArchiver( jarArchiver );
647 
648         MavenArchiveConfiguration config = new MavenArchiveConfiguration();
649         config.setForced( true );
650         config.getManifest().setAddDefaultImplementationEntries( true );
651         config.getManifest().setAddDefaultSpecificationEntries( true );
652         config.getManifest().setMainClass( "org.apache.maven.Foo" );
653         config.getManifest().setAddClasspath( true );
654         config.getManifest().setClasspathLayoutType( ManifestConfiguration.CLASSPATH_LAYOUT_TYPE_REPOSITORY );
655         archiver.createArchive( session, project, config );
656         assertTrue( jarFile.exists() );
657         Manifest manifest = archiver.getManifest( session, project, config );
658         String[] classPathEntries =
659             StringUtils.split( new String( manifest.getMainAttributes().getValue( "Class-Path" ).getBytes() ), " " );
660         assertEquals( "org/apache/dummy/dummy1/1.0/dummy1-1.0.jar", classPathEntries[0] );
661         assertEquals( "org/apache/dummy/foo/dummy2/1.5/dummy2-1.5.jar", classPathEntries[1] );
662         assertEquals( "org/apache/dummy/bar/dummy3/2.0/dummy3-2.0.jar", classPathEntries[2] );
663 
664         String classPath = getJarFileManifest( jarFile ).getMainAttributes().getValue( Attributes.Name.CLASS_PATH );
665         assertNotNull( classPath );
666         classPathEntries = StringUtils.split( classPath, " " );
667         assertEquals( "org/apache/dummy/dummy1/1.0/dummy1-1.0.jar", classPathEntries[0] );
668         assertEquals( "org/apache/dummy/foo/dummy2/1.5/dummy2-1.5.jar", classPathEntries[1] );
669         assertEquals( "org/apache/dummy/bar/dummy3/2.0/dummy3-2.0.jar", classPathEntries[2] );
670     }
671 
672     public void testMavenRepoClassPathValue_WithSnapshot()
673         throws Exception
674     {
675         MavenSession session = getDummySession();
676         MavenProject project = getDummyProjectWithSnapshot();
677         File jarFile = new File( "target/test/dummy.jar" );
678         JarArchiver jarArchiver = getCleanJarArciver( jarFile );
679 
680         MavenArchiver archiver = getMavenArchiver( jarArchiver );
681 
682         MavenArchiveConfiguration config = new MavenArchiveConfiguration();
683         config.setForced( true );
684         config.getManifest().setAddDefaultImplementationEntries( true );
685         config.getManifest().setAddDefaultSpecificationEntries( true );
686         config.getManifest().setMainClass( "org.apache.maven.Foo" );
687         config.getManifest().setAddClasspath( true );
688         config.getManifest().setClasspathLayoutType( ManifestConfiguration.CLASSPATH_LAYOUT_TYPE_REPOSITORY );
689         archiver.createArchive( session, project, config );
690         assertTrue( jarFile.exists() );
691 
692         Manifest manifest = archiver.getManifest( session, project, config );
693         String[] classPathEntries =
694             StringUtils.split( new String( manifest.getMainAttributes().getValue( "Class-Path" ).getBytes() ), " " );
695         assertEquals( "org/apache/dummy/dummy1/1.1-SNAPSHOT/dummy1-1.1-20081022.112233-1.jar", classPathEntries[0] );
696         assertEquals( "org/apache/dummy/foo/dummy2/1.5/dummy2-1.5.jar", classPathEntries[1] );
697         assertEquals( "org/apache/dummy/bar/dummy3/2.0/dummy3-2.0.jar", classPathEntries[2] );
698 
699         String classPath = getJarFileManifest( jarFile ).getMainAttributes().getValue( Attributes.Name.CLASS_PATH );
700         assertNotNull( classPath );
701         classPathEntries = StringUtils.split( classPath, " " );
702         assertEquals( "org/apache/dummy/dummy1/1.1-SNAPSHOT/dummy1-1.1-20081022.112233-1.jar", classPathEntries[0] );
703         assertEquals( "org/apache/dummy/foo/dummy2/1.5/dummy2-1.5.jar", classPathEntries[1] );
704         assertEquals( "org/apache/dummy/bar/dummy3/2.0/dummy3-2.0.jar", classPathEntries[2] );
705     }
706 
707     public void testCustomClassPathValue()
708         throws Exception
709     {
710         MavenSession session = getDummySession();
711         MavenProject project = getDummyProject();
712         File jarFile = new File( "target/test/dummy.jar" );
713         JarArchiver jarArchiver = getCleanJarArciver( jarFile );
714 
715         MavenArchiver archiver = getMavenArchiver( jarArchiver );
716 
717         MavenArchiveConfiguration config = new MavenArchiveConfiguration();
718         config.setForced( true );
719         config.getManifest().setAddDefaultImplementationEntries( true );
720         config.getManifest().setAddDefaultSpecificationEntries( true );
721         config.getManifest().setMainClass( "org.apache.maven.Foo" );
722         config.getManifest().setAddClasspath( true );
723         config.getManifest().setClasspathLayoutType( ManifestConfiguration.CLASSPATH_LAYOUT_TYPE_CUSTOM );
724         config.getManifest().setCustomClasspathLayout(
725             "${artifact.groupIdPath}/${artifact.artifactId}/${artifact.version}/TEST-${artifact.artifactId}-${artifact.version}${dashClassifier?}.${artifact.extension}" );
726         archiver.createArchive( session, project, config );
727         assertTrue( jarFile.exists() );
728         Manifest manifest = archiver.getManifest( session, project, config );
729         String[] classPathEntries =
730             StringUtils.split( new String( manifest.getMainAttributes().getValue( "Class-Path" ).getBytes() ), " " );
731         assertEquals( "org/apache/dummy/dummy1/1.0/TEST-dummy1-1.0.jar", classPathEntries[0] );
732         assertEquals( "org/apache/dummy/foo/dummy2/1.5/TEST-dummy2-1.5.jar", classPathEntries[1] );
733         assertEquals( "org/apache/dummy/bar/dummy3/2.0/TEST-dummy3-2.0.jar", classPathEntries[2] );
734 
735         final Manifest manifest1 = getJarFileManifest( jarFile );
736         String classPath = manifest1.getMainAttributes().getValue( Attributes.Name.CLASS_PATH );
737         assertNotNull( classPath );
738         classPathEntries = StringUtils.split( classPath, " " );
739         assertEquals( "org/apache/dummy/dummy1/1.0/TEST-dummy1-1.0.jar", classPathEntries[0] );
740         assertEquals( "org/apache/dummy/foo/dummy2/1.5/TEST-dummy2-1.5.jar", classPathEntries[1] );
741         assertEquals( "org/apache/dummy/bar/dummy3/2.0/TEST-dummy3-2.0.jar", classPathEntries[2] );
742     }
743 
744     public void testCustomClassPathValue_WithSnapshotResolvedVersion()
745         throws Exception
746     {
747         MavenSession session = getDummySession();
748         MavenProject project = getDummyProjectWithSnapshot();
749         File jarFile = new File( "target/test/dummy.jar" );
750         JarArchiver jarArchiver = getCleanJarArciver( jarFile );
751         MavenArchiver archiver = getMavenArchiver( jarArchiver );
752 
753         MavenArchiveConfiguration config = new MavenArchiveConfiguration();
754         config.setForced( true );
755         config.getManifest().setAddDefaultImplementationEntries( true );
756         config.getManifest().setAddDefaultSpecificationEntries( true );
757         config.getManifest().setMainClass( "org.apache.maven.Foo" );
758         config.getManifest().setAddClasspath( true );
759         config.getManifest().setClasspathLayoutType( ManifestConfiguration.CLASSPATH_LAYOUT_TYPE_CUSTOM );
760         config.getManifest().setCustomClasspathLayout(
761             "${artifact.groupIdPath}/${artifact.artifactId}/${artifact.baseVersion}/TEST-${artifact.artifactId}-${artifact.version}${dashClassifier?}.${artifact.extension}" );
762         archiver.createArchive( session, project, config );
763         assertTrue( jarFile.exists() );
764 
765         Manifest manifest = archiver.getManifest( session, project, config );
766         String[] classPathEntries =
767             StringUtils.split( new String( manifest.getMainAttributes().getValue( "Class-Path" ).getBytes() ), " " );
768         assertEquals( "org/apache/dummy/dummy1/1.1-SNAPSHOT/TEST-dummy1-1.1-20081022.112233-1.jar",
769                       classPathEntries[0] );
770         assertEquals( "org/apache/dummy/foo/dummy2/1.5/TEST-dummy2-1.5.jar", classPathEntries[1] );
771         assertEquals( "org/apache/dummy/bar/dummy3/2.0/TEST-dummy3-2.0.jar", classPathEntries[2] );
772 
773         String classPath = getJarFileManifest( jarFile ).getMainAttributes().getValue( Attributes.Name.CLASS_PATH );
774         assertNotNull( classPath );
775         classPathEntries = StringUtils.split( classPath, " " );
776         assertEquals( "org/apache/dummy/dummy1/1.1-SNAPSHOT/TEST-dummy1-1.1-20081022.112233-1.jar",
777                       classPathEntries[0] );
778         assertEquals( "org/apache/dummy/foo/dummy2/1.5/TEST-dummy2-1.5.jar", classPathEntries[1] );
779         assertEquals( "org/apache/dummy/bar/dummy3/2.0/TEST-dummy3-2.0.jar", classPathEntries[2] );
780     }
781 
782     public void testCustomClassPathValue_WithSnapshotForcingBaseVersion()
783         throws Exception
784     {
785         MavenSession session = getDummySession();
786         MavenProject project = getDummyProjectWithSnapshot();
787         File jarFile = new File( "target/test/dummy.jar" );
788         JarArchiver jarArchiver = getCleanJarArciver( jarFile );
789 
790         MavenArchiver archiver = getMavenArchiver( jarArchiver );
791 
792         MavenArchiveConfiguration config = new MavenArchiveConfiguration();
793         config.setForced( true );
794         config.getManifest().setAddDefaultImplementationEntries( true );
795         config.getManifest().setAddDefaultSpecificationEntries( true );
796         config.getManifest().setMainClass( "org.apache.maven.Foo" );
797         config.getManifest().setAddClasspath( true );
798         config.getManifest().setClasspathLayoutType( ManifestConfiguration.CLASSPATH_LAYOUT_TYPE_CUSTOM );
799         config.getManifest().setCustomClasspathLayout(
800             "${artifact.groupIdPath}/${artifact.artifactId}/${artifact.baseVersion}/TEST-${artifact.artifactId}-${artifact.baseVersion}${dashClassifier?}.${artifact.extension}" );
801         archiver.createArchive( session, project, config );
802         assertTrue( jarFile.exists() );
803         Manifest manifest = archiver.getManifest( session, project, config );
804         String[] classPathEntries =
805             StringUtils.split( new String( manifest.getMainAttributes().getValue( "Class-Path" ).getBytes() ), " " );
806         assertEquals( "org/apache/dummy/dummy1/1.1-SNAPSHOT/TEST-dummy1-1.1-SNAPSHOT.jar", classPathEntries[0] );
807         assertEquals( "org/apache/dummy/foo/dummy2/1.5/TEST-dummy2-1.5.jar", classPathEntries[1] );
808         assertEquals( "org/apache/dummy/bar/dummy3/2.0/TEST-dummy3-2.0.jar", classPathEntries[2] );
809 
810         String classPath = getJarFileManifest( jarFile ).getMainAttributes().getValue( Attributes.Name.CLASS_PATH );
811         assertNotNull( classPath );
812         classPathEntries = StringUtils.split( classPath, " " );
813         assertEquals( "org/apache/dummy/dummy1/1.1-SNAPSHOT/TEST-dummy1-1.1-SNAPSHOT.jar", classPathEntries[0] );
814         assertEquals( "org/apache/dummy/foo/dummy2/1.5/TEST-dummy2-1.5.jar", classPathEntries[1] );
815         assertEquals( "org/apache/dummy/bar/dummy3/2.0/TEST-dummy3-2.0.jar", classPathEntries[2] );
816     }
817 
818     private JarArchiver getCleanJarArciver( File jarFile )
819     {
820         deleteAndAssertNotPresent( jarFile );
821         JarArchiver jarArchiver = new JarArchiver();
822         jarArchiver.setDestFile( jarFile );
823         return jarArchiver;
824     }
825 
826     // ----------------------------------------
827     // common methods for testing
828     // ----------------------------------------
829 
830     private MavenProject getDummyProject()
831     {
832         MavenProject project = getMavenProject();
833         File pomFile = new File( "src/test/resources/pom.xml" );
834         pomFile.setLastModified( System.currentTimeMillis() - 60000L );
835         project.setFile( pomFile );
836         Build build = new Build();
837         build.setDirectory( "target" );
838         build.setOutputDirectory( "target" );
839         project.setBuild( build );
840         project.setName( "archiver test" );
841         project.setUrl( "http://maven.apache.org" );
842         Organization organization = new Organization();
843         organization.setName( "Apache" );
844         project.setOrganization( organization );
845         MockArtifact artifact = new MockArtifact();
846         artifact.setGroupId( "org.apache.dummy" );
847         artifact.setArtifactId( "dummy" );
848         artifact.setVersion( "0.1" );
849         artifact.setBaseVersion( "0.1" );
850         artifact.setType( "jar" );
851         artifact.setArtifactHandler( new DefaultArtifactHandler( "jar" ) );
852         project.setArtifact( artifact );
853 
854         Set<Artifact> artifacts = getArtifacts( getMockArtifact1Release(), getMockArtifact2(), getMockArtifact3() );
855         project.setArtifacts( artifacts );
856 
857         return project;
858     }
859 
860     private MavenProject getMavenProject()
861     {
862         Model model = new Model();
863         model.setGroupId( "org.apache.dummy" );
864         model.setArtifactId( "dummy" );
865         model.setVersion( "0.1" );
866 
867         final MavenProject project = new MavenProject( model );
868         project.setPluginArtifacts( Collections.EMPTY_SET );
869         project.setReportArtifacts( Collections.EMPTY_SET );
870         project.setExtensionArtifacts( Collections.EMPTY_SET );
871         project.setRemoteArtifactRepositories( Collections.EMPTY_LIST );
872         project.setPluginArtifactRepositories( Collections.EMPTY_LIST );
873         return project;
874     }
875 
876 
877     private MockArtifact getMockArtifact3()
878     {
879         MockArtifact artifact3 = new MockArtifact();
880         artifact3.setGroupId( "org.apache.dummy.bar" );
881         artifact3.setArtifactId( "dummy3" );
882         artifact3.setVersion( "2.0" );
883         artifact3.setScope( "runtime" );
884         artifact3.setType( "jar" );
885         artifact3.setFile( getClasspathFile( artifact3.getArtifactId() + "-" + artifact3.getVersion() + ".jar" ) );
886         return artifact3;
887     }
888 
889     private MavenProject getDummyProjectWithSnapshot()
890     {
891         MavenProject project = getMavenProject();
892         File pomFile = new File( "src/test/resources/pom.xml" );
893         pomFile.setLastModified( System.currentTimeMillis() - 60000L );
894         project.setFile( pomFile );
895         Build build = new Build();
896         build.setDirectory( "target" );
897         build.setOutputDirectory( "target" );
898         project.setBuild( build );
899         project.setName( "archiver test" );
900         Organization organization = new Organization();
901         organization.setName( "Apache" );
902         project.setOrganization( organization );
903 
904         MockArtifact artifact = new MockArtifact();
905         artifact.setGroupId( "org.apache.dummy" );
906         artifact.setArtifactId( "dummy" );
907         artifact.setVersion( "0.1" );
908         artifact.setBaseVersion( "0.1" );
909         artifact.setType( "jar" );
910         artifact.setArtifactHandler( new DefaultArtifactHandler( "jar" ) );
911         project.setArtifact( artifact );
912 
913         Set<Artifact> artifacts = getArtifacts( getMockArtifact1(), getMockArtifact2(), getMockArtifact3() );
914 
915         project.setArtifacts( artifacts );
916 
917         return project;
918     }
919 
920     private ArtifactHandler getMockArtifactHandler()
921     {
922         return new ArtifactHandler()
923         {
924 
925             public String getClassifier()
926             {
927                 return null;
928             }
929 
930             public String getDirectory()
931             {
932                 return null;
933             }
934 
935             public String getExtension()
936             {
937                 return "jar";
938             }
939 
940             public String getLanguage()
941             {
942                 return null;
943             }
944 
945             public String getPackaging()
946             {
947                 return null;
948             }
949 
950             public boolean isAddedToClasspath()
951             {
952                 return true;
953             }
954 
955             public boolean isIncludesDependencies()
956             {
957                 return false;
958             }
959 
960         };
961     }
962 
963     private MockArtifact getMockArtifact2()
964     {
965         MockArtifact artifact2 = new MockArtifact();
966         artifact2.setGroupId( "org.apache.dummy.foo" );
967         artifact2.setArtifactId( "dummy2" );
968         artifact2.setVersion( "1.5" );
969         artifact2.setType( "jar" );
970         artifact2.setScope( "runtime" );
971         artifact2.setFile( getClasspathFile( artifact2.getArtifactId() + "-" + artifact2.getVersion() + ".jar" ) );
972         return artifact2;
973     }
974 
975     private MockArtifact getArtifactWithDot()
976     {
977         MockArtifact artifact2 = new MockArtifact();
978         artifact2.setGroupId( "org.apache.dummy.foo" );
979         artifact2.setArtifactId( "dummy.dot" );
980         artifact2.setVersion( "1.5" );
981         artifact2.setType( "jar" );
982         artifact2.setScope( "runtime" );
983         artifact2.setFile( getClasspathFile( artifact2.getArtifactId() + "-" + artifact2.getVersion() + ".jar" ) );
984         return artifact2;
985     }
986 
987     private MockArtifact getMockArtifact1()
988     {
989         MockArtifact artifact1 = new MockArtifact();
990         artifact1.setGroupId( "org.apache.dummy" );
991         artifact1.setArtifactId( "dummy1" );
992         artifact1.setSnapshotVersion( "1.1-20081022.112233-1", "1.1-SNAPSHOT" );
993         artifact1.setType( "jar" );
994         artifact1.setScope( "runtime" );
995         artifact1.setFile( getClasspathFile( artifact1.getArtifactId() + "-" + artifact1.getVersion() + ".jar" ) );
996         return artifact1;
997     }
998 
999     private MockArtifact getMockArtifact1Release()
1000     {
1001         MockArtifact artifact1 = new MockArtifact();
1002         artifact1.setGroupId( "org.apache.dummy" );
1003         artifact1.setArtifactId( "dummy1" );
1004         artifact1.setVersion( "1.0" );
1005         artifact1.setType( "jar" );
1006         artifact1.setScope( "runtime" );
1007         artifact1.setFile( getClasspathFile( artifact1.getArtifactId() + "-" + artifact1.getVersion() + ".jar" ) );
1008         return artifact1;
1009     }
1010 
1011     private File getClasspathFile( String file )
1012     {
1013         URL resource = Thread.currentThread().getContextClassLoader().getResource( file );
1014         if ( resource == null )
1015         {
1016             fail( "Cannot retrieve java.net.URL for file: " + file + " on the current test classpath." );
1017         }
1018 
1019         URI uri = new File( resource.getPath() ).toURI().normalize();
1020 
1021         return new File( uri.getPath().replaceAll( "%20", " " ) );
1022     }
1023 
1024     private MavenSession getDummySession()
1025     {
1026         Properties executionProperties = new Properties();
1027         executionProperties.put( "maven.version", "3.0.4" );
1028 
1029         return getDummySession( executionProperties );
1030     }
1031 
1032     private MavenSession getDummySessionWithoutMavenVersion()
1033     {
1034         return getDummySession( new Properties() );
1035     }
1036 
1037     private MavenSession getDummySession( Properties executionProperties )
1038     {
1039         PlexusContainer container = null;
1040         Settings settings = null;
1041         ArtifactRepository localRepo = null;
1042         EventDispatcher eventDispatcher = null;
1043         ReactorManager reactorManager = null;
1044         List<?> goals = null;
1045         String executionRootDir = null;
1046         Date startTime = new Date();
1047 
1048         return new MavenSession( container, settings, localRepo, eventDispatcher, reactorManager, goals,
1049                                  executionRootDir, executionProperties, startTime );
1050     }
1051 
1052     private Set<Artifact> getArtifacts( Artifact... artifacts )
1053     {
1054         final ArtifactHandler mockArtifactHandler = getMockArtifactHandler();
1055         Set<Artifact> result = new TreeSet<Artifact>( new ArtifactComparator() );
1056         for ( Artifact artifact : artifacts )
1057         {
1058             artifact.setArtifactHandler( mockArtifactHandler );
1059             result.add( artifact );
1060         }
1061         return result;
1062     }
1063 
1064     public Manifest getJarFileManifest( File jarFile )
1065         throws IOException
1066     {
1067         JarFile jar = null;
1068         try
1069         {
1070             jar = new JarFile( jarFile );
1071             return jar.getManifest();
1072         }
1073         finally
1074         {
1075             if ( jar != null )
1076             {
1077                 jar.close();
1078             }
1079         }
1080 
1081     }
1082 }