1   package org.apache.maven.plugin.dependency;
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 java.io.File;
23  import java.io.IOException;
24  import java.util.HashSet;
25  import java.util.Iterator;
26  import java.util.Set;
27  
28  import org.apache.maven.artifact.Artifact;
29  import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
30  import org.apache.maven.plugin.MojoExecutionException;
31  import org.apache.maven.plugin.dependency.testUtils.DependencyArtifactStubFactory;
32  import org.apache.maven.plugin.dependency.testUtils.DependencyTestUtils;
33  import org.apache.maven.plugin.dependency.utils.DependencyUtil;
34  import org.apache.maven.plugin.dependency.utils.markers.DefaultFileMarkerHandler;
35  import org.apache.maven.plugin.testing.stubs.StubArtifactRepository;
36  import org.apache.maven.plugin.testing.stubs.StubArtifactResolver;
37  import org.apache.maven.project.MavenProject;
38  import org.codehaus.plexus.util.StringUtils;
39  
40  public class TestUnpackDependenciesMojo
41      extends AbstractDependencyMojoTestCase
42  {
43  
44      private final String UNPACKABLE_FILE = "test.txt";
45  
46      private final String UNPACKABLE_FILE_PATH = "target/test-classes/unit/unpack-dependencies-test/" + UNPACKABLE_FILE;
47  
48      UnpackDependenciesMojo mojo;
49  
50      protected void setUp()
51          throws Exception
52      {
53          // required for mojo lookups to work
54          super.setUp( "unpack-dependencies", true );
55  
56          File testPom = new File( getBasedir(), "target/test-classes/unit/unpack-dependencies-test/plugin-config.xml" );
57          mojo = (UnpackDependenciesMojo) lookupMojo( "unpack-dependencies", testPom );
58          mojo.outputDirectory = new File( this.testDir, "outputDirectory" );
59          // mojo.silent = true;
60  
61          // it needs to get the archivermanager
62          stubFactory.setUnpackableFile( mojo.getArchiverManager() );
63          // i'm using one file repeatedly to archive so I can test the name
64          // programmatically.
65          stubFactory.setSrcFile( new File( getBasedir() + File.separatorChar + UNPACKABLE_FILE_PATH ) );
66  
67          assertNotNull( mojo );
68          assertNotNull( mojo.getProject() );
69          MavenProject project = mojo.getProject();
70  
71          Set artifacts = this.stubFactory.getScopedArtifacts();
72          Set directArtifacts = this.stubFactory.getReleaseAndSnapshotArtifacts();
73          artifacts.addAll( directArtifacts );
74  
75          project.setArtifacts( artifacts );
76          project.setDependencyArtifacts( directArtifacts );
77          mojo.markersDirectory = new File( this.testDir, "markers" );
78  
79      }
80      
81      protected void tearDown()
82      {
83          super.tearDown();
84          
85          mojo = null;
86          System.gc();
87      }
88  
89      public void assertUnpacked( Artifact artifact )
90      {                
91          assertUnpacked( true, artifact );
92      }
93  
94      public void assertUnpacked( boolean val, Artifact artifact )
95      {
96          File folder = DependencyUtil.getFormattedOutputDirectory( mojo.useSubDirectoryPerType,
97                                                                    mojo.useSubDirectoryPerArtifact,
98                                                                    mojo.useRepositoryLayout, mojo.stripVersion,
99                                                                    mojo.outputDirectory, artifact );
100 
101         File destFile = new File( folder, DependencyArtifactStubFactory.getUnpackableFileName( artifact ) );
102 
103         assertEquals( val, destFile.exists() );
104         assertMarkerFile( val, artifact );
105     }
106 
107     public void assertMarkerFile( boolean val, Artifact artifact )
108     {
109         DefaultFileMarkerHandler handle = new DefaultFileMarkerHandler( artifact, mojo.markersDirectory );
110         try
111         {
112             assertEquals( val, handle.isMarkerSet() );
113         }
114         catch ( MojoExecutionException e )
115         {
116             fail( e.getLongMessage() );
117         }
118     }
119 
120     public void testMojo()
121         throws Exception
122     {
123         mojo.execute();
124         Iterator iter = mojo.project.getArtifacts().iterator();
125         while ( iter.hasNext() )
126         {
127             Artifact artifact = (Artifact) iter.next();
128             assertUnpacked( artifact );
129         }
130     }
131 
132     public void testNoTransitive()
133         throws Exception
134     {
135         mojo.excludeTransitive = true;
136         mojo.execute();
137         Iterator iter = mojo.project.getDependencyArtifacts().iterator();
138         while ( iter.hasNext() )
139         {
140             Artifact artifact = (Artifact) iter.next();
141             assertUnpacked( artifact );
142         }
143     }
144 
145     public void testExcludeType()
146         throws Exception
147     {
148         mojo.project.setArtifacts( stubFactory.getTypedArchiveArtifacts() );
149         mojo.project.setDependencyArtifacts( new HashSet() );
150         mojo.excludeTypes = "jar";
151         mojo.execute();
152 
153         Iterator iter = mojo.project.getArtifacts().iterator();
154         while ( iter.hasNext() )
155         {
156             Artifact artifact = (Artifact) iter.next();
157 
158             assertUnpacked( !artifact.getType().equalsIgnoreCase( "jar" ), artifact );
159         }
160     }
161 
162     public void testExcludeProvidedScope()
163         throws Exception
164     {
165         mojo.project.setArtifacts( stubFactory.getScopedArtifacts() );
166         mojo.project.setDependencyArtifacts( new HashSet() );
167         mojo.excludeScope = "provided";
168         // mojo.silent = false;
169 
170         mojo.execute();
171 
172         Iterator iter = mojo.project.getArtifacts().iterator();
173         while ( iter.hasNext() )
174         {
175             Artifact artifact = (Artifact) iter.next();
176             assertUnpacked( !artifact.getScope().equals( "provided" ), artifact );
177         }
178 
179     }
180 
181     public void testExcludeSystemScope()
182         throws Exception
183     {
184         mojo.project.setArtifacts( stubFactory.getScopedArtifacts() );
185         mojo.project.setDependencyArtifacts( new HashSet() );
186         mojo.excludeScope = "system";
187         // mojo.silent = false;
188 
189         mojo.execute();
190 
191         Iterator iter = mojo.project.getArtifacts().iterator();
192         while ( iter.hasNext() )
193         {
194             Artifact artifact = (Artifact) iter.next();
195             assertUnpacked( !artifact.getScope().equals( "system" ), artifact );
196         }
197 
198     }
199 
200     public void testExcludeCompileScope()
201         throws Exception
202     {
203         mojo.project.setArtifacts( stubFactory.getScopedArtifacts() );
204         mojo.project.setDependencyArtifacts( new HashSet() );
205         mojo.excludeScope = "compile";
206         mojo.execute();
207         ScopeArtifactFilter saf = new ScopeArtifactFilter( mojo.excludeScope );
208 
209         Iterator iter = mojo.project.getArtifacts().iterator();
210         while ( iter.hasNext() )
211         {
212             Artifact artifact = (Artifact) iter.next();
213             assertUnpacked( !saf.include( artifact ), artifact );
214         }
215     }
216 
217     public void testExcludeTestScope()
218         throws IOException
219     {
220         mojo.project.setArtifacts( stubFactory.getScopedArtifacts() );
221         mojo.project.setDependencyArtifacts( new HashSet() );
222         mojo.excludeScope = "test";
223 
224         try
225         {
226             mojo.execute();
227             fail( "expected an exception" );
228         }
229         catch ( MojoExecutionException e )
230         {
231 
232         }
233 
234     }
235 
236     public void testExcludeRuntimeScope()
237         throws Exception
238     {
239         mojo.project.setArtifacts( stubFactory.getScopedArtifacts() );
240         mojo.project.setDependencyArtifacts( new HashSet() );
241         mojo.excludeScope = "runtime";
242         mojo.execute();
243         ScopeArtifactFilter saf = new ScopeArtifactFilter( mojo.excludeScope );
244 
245         Iterator iter = mojo.project.getArtifacts().iterator();
246         while ( iter.hasNext() )
247         {
248             Artifact artifact = (Artifact) iter.next();
249             assertUnpacked( !saf.include( artifact ), artifact );
250         }
251     }
252 
253     public void testIncludeType()
254         throws Exception
255     {
256         mojo.project.setArtifacts( stubFactory.getTypedArchiveArtifacts() );
257         mojo.project.setDependencyArtifacts( new HashSet() );
258 
259         mojo.includeTypes = "jar";
260         mojo.excludeTypes = "jar";
261         //shouldn't get anything
262 
263         mojo.execute();
264 
265         Iterator iter = mojo.project.getArtifacts().iterator();
266         while ( iter.hasNext() )
267         {
268             Artifact artifact = (Artifact) iter.next();
269 
270             assertUnpacked( false, artifact );
271         }
272         
273         mojo.excludeTypes = "";
274         mojo.execute();
275 
276         iter = mojo.project.getArtifacts().iterator();
277         while ( iter.hasNext() )
278         {
279             Artifact artifact = (Artifact) iter.next();
280 
281             assertUnpacked( artifact.getType().equalsIgnoreCase( "jar" ), artifact );
282         }
283     }
284 
285     public void testSubPerType()
286         throws Exception
287     {
288         mojo.project.setArtifacts( stubFactory.getTypedArchiveArtifacts() );
289         mojo.project.setDependencyArtifacts( new HashSet() );
290         mojo.useSubDirectoryPerType = true;
291         mojo.execute();
292 
293         Iterator iter = mojo.project.getArtifacts().iterator();
294         while ( iter.hasNext() )
295         {
296             Artifact artifact = (Artifact) iter.next();
297             assertUnpacked( artifact );
298         }
299     }
300 
301     public void testSubPerArtifact()
302         throws Exception
303     {
304         mojo.useSubDirectoryPerArtifact = true;
305         mojo.execute();
306 
307         Iterator iter = mojo.project.getArtifacts().iterator();
308         while ( iter.hasNext() )
309         {
310             Artifact artifact = (Artifact) iter.next();
311             assertUnpacked( artifact );
312         }
313     }
314 
315     public void testSubPerArtifactAndType()
316         throws Exception
317     {
318         mojo.project.setArtifacts( stubFactory.getTypedArchiveArtifacts() );
319         mojo.project.setDependencyArtifacts( new HashSet() );
320         mojo.useSubDirectoryPerArtifact = true;
321         mojo.useSubDirectoryPerType = true;
322         mojo.execute();
323 
324         Iterator iter = mojo.project.getArtifacts().iterator();
325         while ( iter.hasNext() )
326         {
327             Artifact artifact = (Artifact) iter.next();
328             assertUnpacked( artifact );
329         }
330     }
331 
332     public void testSubPerArtifactRemoveVersion()
333         throws Exception
334     {
335         mojo.useSubDirectoryPerArtifact = true;
336         mojo.stripVersion = true;
337         mojo.execute();
338 
339         Iterator iter = mojo.project.getArtifacts().iterator();
340         while ( iter.hasNext() )
341         {
342             Artifact artifact = (Artifact) iter.next();
343             assertUnpacked( artifact );
344         }
345     }
346 
347     public void testSubPerArtifactAndTypeRemoveVersion()
348         throws Exception
349     {
350         mojo.project.setArtifacts( stubFactory.getTypedArchiveArtifacts() );
351         mojo.project.setDependencyArtifacts( new HashSet() );
352         mojo.useSubDirectoryPerArtifact = true;
353         mojo.useSubDirectoryPerType = true;
354         mojo.stripVersion = true;
355         mojo.execute();
356 
357         Iterator iter = mojo.project.getArtifacts().iterator();
358         while ( iter.hasNext() )
359         {
360             Artifact artifact = (Artifact) iter.next();
361             assertUnpacked( artifact );
362         }
363     }
364 
365     public void testIncludeCompileScope()
366         throws Exception
367     {
368         mojo.project.setArtifacts( stubFactory.getScopedArtifacts() );
369         mojo.project.setDependencyArtifacts( new HashSet() );
370         mojo.includeScope = "compile";
371         mojo.execute();
372         ScopeArtifactFilter saf = new ScopeArtifactFilter( mojo.includeScope );
373 
374         Iterator iter = mojo.project.getArtifacts().iterator();
375         while ( iter.hasNext() )
376         {
377             Artifact artifact = (Artifact) iter.next();
378             assertUnpacked( saf.include( artifact ), artifact );
379         }
380     }
381 
382     public void testIncludeTestScope()
383         throws Exception
384     {
385         mojo.project.setArtifacts( stubFactory.getScopedArtifacts() );
386         mojo.project.setDependencyArtifacts( new HashSet() );
387         mojo.includeScope = "test";
388 
389         mojo.execute();
390         ScopeArtifactFilter saf = new ScopeArtifactFilter( mojo.includeScope );
391 
392         Iterator iter = mojo.project.getArtifacts().iterator();
393         while ( iter.hasNext() )
394         {
395             Artifact artifact = (Artifact) iter.next();
396             assertUnpacked( saf.include( artifact ), artifact );
397         }
398     }
399 
400     public void testIncludeRuntimeScope()
401         throws Exception
402     {
403         mojo.project.setArtifacts( stubFactory.getScopedArtifacts() );
404         mojo.project.setDependencyArtifacts( new HashSet() );
405         mojo.includeScope = "runtime";
406         mojo.execute();
407         ScopeArtifactFilter saf = new ScopeArtifactFilter( mojo.includeScope );
408 
409         Iterator iter = mojo.project.getArtifacts().iterator();
410         while ( iter.hasNext() )
411         {
412             Artifact artifact = (Artifact) iter.next();
413             assertUnpacked( saf.include( artifact ), artifact );
414         }
415     }
416 
417     public void testIncludeprovidedScope()
418         throws Exception
419     {
420         mojo.project.setArtifacts( stubFactory.getScopedArtifacts() );
421         mojo.project.setDependencyArtifacts( new HashSet() );
422         mojo.includeScope = "provided";
423 
424         mojo.execute();
425         Iterator iter = mojo.project.getArtifacts().iterator();
426         while ( iter.hasNext() )
427         {
428             Artifact artifact = (Artifact) iter.next();
429             assertUnpacked( Artifact.SCOPE_PROVIDED.equals( artifact.getScope() ), artifact );
430         }
431     }
432 
433     public void testIncludesystemScope()
434         throws Exception
435     {
436         mojo.project.setArtifacts( stubFactory.getScopedArtifacts() );
437         mojo.project.setDependencyArtifacts( new HashSet() );
438         mojo.includeScope = "system";
439 
440         mojo.execute();
441 
442         Iterator iter = mojo.project.getArtifacts().iterator();
443         while ( iter.hasNext() )
444         {
445             Artifact artifact = (Artifact) iter.next();
446             assertUnpacked( Artifact.SCOPE_SYSTEM.equals( artifact.getScope() ), artifact );
447         }
448     }
449 
450     public void testIncludeArtifactId()
451         throws Exception
452     {
453         mojo.project.setArtifacts( stubFactory.getArtifactArtifacts() );
454         mojo.project.setDependencyArtifacts( new HashSet() );
455 
456         mojo.includeArtifactIds = "one";
457         mojo.excludeArtifactIds = "one";
458         //shouldn't get anything
459         mojo.execute();
460 
461         Iterator iter = mojo.project.getArtifacts().iterator();
462         while ( iter.hasNext() )
463         {
464             Artifact artifact = (Artifact) iter.next();
465             assertUnpacked( false, artifact );
466         }
467         mojo.excludeArtifactIds ="";
468         mojo.execute();
469 
470         iter = mojo.project.getArtifacts().iterator();
471         while ( iter.hasNext() )
472         {
473             Artifact artifact = (Artifact) iter.next();
474             assertUnpacked( artifact.getArtifactId().equals( "one" ), artifact );
475         }
476 
477     }
478 
479     public void testExcludeArtifactId()
480         throws Exception
481     {
482         mojo.project.setArtifacts( stubFactory.getArtifactArtifacts() );
483         mojo.project.setDependencyArtifacts( new HashSet() );
484         mojo.excludeArtifactIds = "one";
485         mojo.execute();
486 
487         // test - get all direct dependencies and verify that they exist if they
488         // do not have a classifier of "one"
489         // then delete the file and at the end, verify the folder is empty.
490         Iterator iter = mojo.project.getArtifacts().iterator();
491         while ( iter.hasNext() )
492         {
493             Artifact artifact = (Artifact) iter.next();
494             assertUnpacked( !artifact.getArtifactId().equals( "one" ), artifact );
495         }
496     }
497 
498     public void testExcludeGroupId()
499         throws Exception
500     {
501         mojo.project.setArtifacts( stubFactory.getGroupIdArtifacts() );
502         mojo.project.setDependencyArtifacts( new HashSet() );
503         mojo.excludeGroupIds = "one";
504         mojo.execute();
505 
506         Iterator iter = mojo.project.getArtifacts().iterator();
507         while ( iter.hasNext() )
508         {
509             Artifact artifact = (Artifact) iter.next();
510             assertUnpacked( !artifact.getGroupId().equals( "one" ), artifact );
511         }
512     }
513 
514     public void testIncludeGroupId()
515         throws Exception
516     {
517         mojo.project.setArtifacts( stubFactory.getGroupIdArtifacts() );
518         mojo.project.setDependencyArtifacts( new HashSet() );
519         mojo.includeGroupIds = "one";
520         mojo.excludeGroupIds = "one";
521         //shouldn't get anything
522         
523         mojo.execute();
524 
525         Iterator iter = mojo.project.getArtifacts().iterator();
526         while ( iter.hasNext() )
527         {
528             Artifact artifact = (Artifact) iter.next();
529             // Testing with artifact id because group id is not in filename
530             assertUnpacked( false, artifact );
531         }
532         
533         mojo.excludeGroupIds = "";
534         mojo.execute();
535 
536         iter = mojo.project.getArtifacts().iterator();
537         while ( iter.hasNext() )
538         {
539             Artifact artifact = (Artifact) iter.next();
540             // Testing with artifact id because group id is not in filename
541             assertUnpacked( artifact.getGroupId().equals( "one" ), artifact );
542         }
543         
544     }
545 
546     public void testCDMClassifier()
547         throws Exception
548     {
549         dotestClassifierType( "jdk14", null );
550     }
551 
552     public void testCDMType()
553         throws Exception
554     {
555         dotestClassifierType( null, "zip" );
556     }
557 
558     public void testCDMClassifierType()
559         throws Exception
560     {
561         dotestClassifierType( "jdk14", "war" );
562     }
563 
564     public void dotestClassifierType( String testClassifier, String testType )
565         throws Exception
566     {
567         mojo.classifier = testClassifier;
568         mojo.type = testType;
569         mojo.factory = DependencyTestUtils.getArtifactFactory();
570         mojo.resolver = new StubArtifactResolver( stubFactory, false, false );
571         mojo.local = new StubArtifactRepository( this.testDir.getAbsolutePath() );
572 
573         mojo.execute();
574 
575         Iterator iter = mojo.project.getArtifacts().iterator();
576         while ( iter.hasNext() )
577         {
578             Artifact artifact = (Artifact) iter.next();
579 
580             String useClassifier = artifact.getClassifier();
581             String useType = artifact.getType();
582 
583             if ( StringUtils.isNotEmpty( testClassifier ) )
584             {
585                 useClassifier = testClassifier;
586                 // type is only used if classifier is used.
587                 if ( StringUtils.isNotEmpty( testType ) )
588                 {
589                     useType = testType;
590                 }
591             }
592             Artifact unpacked = stubFactory.createArtifact( artifact.getGroupId(), artifact.getArtifactId(), artifact
593                 .getVersion(), Artifact.SCOPE_COMPILE, useType, useClassifier );
594             assertUnpacked( unpacked );
595         }
596     }
597 
598     public void testArtifactNotFound()
599         throws Exception
600     {
601         dotestArtifactExceptions( false, true );
602     }
603 
604     public void testArtifactResolutionException()
605         throws Exception
606     {
607         dotestArtifactExceptions( true, false );
608     }
609 
610     public void dotestArtifactExceptions( boolean are, boolean anfe )
611         throws Exception
612     {
613         mojo.classifier = "jdk";
614         mojo.type = "java-sources";
615         // init classifier things
616         mojo.setFactory( DependencyTestUtils.getArtifactFactory() );
617         mojo.setResolver( new StubArtifactResolver( null, are, anfe ) );
618         mojo.setLocal( new StubArtifactRepository( this.testDir.getAbsolutePath() ) );
619 
620         try
621         {
622             mojo.execute();
623             fail( "ExpectedException" );
624         }
625         catch ( MojoExecutionException e )
626         {
627         }
628     }
629 
630     public File getUnpackedFile( Artifact artifact )
631     {
632         File destDir = DependencyUtil.getFormattedOutputDirectory( mojo.isUseSubDirectoryPerType(), mojo
633             .isUseSubDirectoryPerArtifact(), mojo.useRepositoryLayout, mojo.stripVersion, mojo.getOutputDirectory(),
634                                                                    artifact );
635         File unpacked = new File( destDir, DependencyArtifactStubFactory.getUnpackableFileName( artifact ) );
636         assertTrue( unpacked.exists() );
637         return unpacked;
638     }
639 
640     public DefaultFileMarkerHandler getUnpackedMarkerHandler( Artifact artifact )
641     {
642         return new DefaultFileMarkerHandler( artifact, mojo.getMarkersDirectory() );
643     }
644 
645    
646     public void assertUnpacked( Artifact artifact, boolean overWrite )
647         throws InterruptedException, MojoExecutionException
648     {
649         File unpackedFile = getUnpackedFile( artifact );
650 
651         Thread.sleep( 100 );
652         // round down to the last second
653         long time = System.currentTimeMillis();
654         time = time - ( time % 1000 );
655         unpackedFile.setLastModified( time );
656         // wait at least a second for filesystems that only record to the
657         // nearest second.
658         Thread.sleep( 1000 );
659 
660         assertEquals( time, unpackedFile.lastModified() );
661         mojo.execute();
662 
663         if ( overWrite )
664         {
665             assertTrue( time != unpackedFile.lastModified() );
666         }
667         else
668         {
669             assertEquals( time, unpackedFile.lastModified() );
670         }
671     }
672 }