1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  package org.codehaus.mojo.license;
17  
18  import org.apache.maven.artifact.Artifact;
19  import org.apache.maven.artifact.repository.ArtifactRepository;
20  import org.apache.maven.model.License;
21  import org.apache.maven.plugin.AbstractMojo;
22  import org.apache.maven.plugin.MojoExecutionException;
23  import org.apache.maven.project.MavenProject;
24  import org.codehaus.mojo.license.model.ProjectLicenseInfo;
25  
26  import java.io.File;
27  import java.io.FileInputStream;
28  import java.io.FileNotFoundException;
29  import java.io.IOException;
30  import java.net.MalformedURLException;
31  import java.net.URL;
32  import java.util.*;
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  public class DownloadLicensesMojo
46      extends AbstractMojo
47      implements MavenProjectDependenciesConfigurator
48  {
49  
50      
51  
52  
53  
54  
55  
56  
57      private MavenProject project;
58  
59      
60  
61  
62  
63  
64  
65  
66      private ArtifactRepository localRepository;
67  
68      
69  
70  
71  
72  
73  
74  
75      private List remoteRepositories;
76  
77      
78  
79  
80  
81  
82  
83      private File licensesConfigFile;
84  
85      
86  
87  
88  
89  
90  
91      private File licensesOutputDirectory;
92  
93      
94  
95  
96  
97  
98  
99      private File licensesOutputFile;
100 
101     
102 
103 
104 
105 
106 
107     private String excludedScopes;
108 
109     
110 
111 
112 
113 
114 
115     private String includedScopes;
116 
117     
118 
119 
120 
121 
122 
123     private boolean offline;
124 
125     
126 
127 
128 
129 
130 
131     private boolean quiet;
132 
133     
134 
135 
136 
137 
138 
139     private boolean includeTransitiveDependencies;
140 
141     
142 
143 
144 
145 
146 
147 
148     private DependenciesTool dependenciesTool;
149 
150     
151 
152 
153 
154     private Set<String> downloadedLicenseURLs = new HashSet<String>();
155 
156     
157 
158 
159     public void execute()
160         throws MojoExecutionException
161     {
162 
163         if ( offline )
164         {
165 
166             getLog().warn( "Offline flag is on, download-licenses goal is skip." );
167             return;
168         }
169         initDirectories();
170 
171         Map<String, ProjectLicenseInfo> configuredDepLicensesMap = new HashMap<String, ProjectLicenseInfo>();
172 
173         
174         if ( licensesOutputFile.exists() )
175         {
176             loadLicenseInfo( configuredDepLicensesMap, licensesOutputFile, true );
177         }
178 
179         
180         if ( licensesConfigFile.exists() )
181         {
182             loadLicenseInfo( configuredDepLicensesMap, licensesConfigFile, false );
183         }
184 
185         SortedMap<String, MavenProject> dependencies =
186             dependenciesTool.loadProjectDependencies( project, this, localRepository, remoteRepositories, null );
187 
188         
189         List<ProjectLicenseInfo> depProjectLicenses = new ArrayList<ProjectLicenseInfo>();
190 
191         for ( MavenProject project : dependencies.values() )
192         {
193             Artifact artifact = project.getArtifact();
194             getLog().debug( "Checking licenses for project " + artifact );
195             String artifactProjectId = getArtifactProjectId( artifact );
196             ProjectLicenseInfo depProject;
197             if ( configuredDepLicensesMap.containsKey( artifactProjectId ) )
198             {
199                 depProject = configuredDepLicensesMap.get( artifactProjectId );
200                 depProject.setVersion( artifact.getVersion() );
201             }
202             else
203             {
204                 depProject = createDependencyProject( project );
205             }
206             downloadLicenses( depProject );
207             depProjectLicenses.add( depProject );
208         }
209 
210         try
211         {
212             LicenseSummaryWriter.writeLicenseSummary( depProjectLicenses, licensesOutputFile );
213         }
214         catch ( Exception e )
215         {
216             throw new MojoExecutionException( "Unable to write license summary file: " + licensesOutputFile, e );
217         }
218 
219     }
220 
221     private void initDirectories()
222         throws MojoExecutionException
223     {
224         try
225         {
226             FileUtil.createDirectoryIfNecessary( licensesOutputDirectory );
227 
228             FileUtil.createDirectoryIfNecessary( licensesOutputFile.getParentFile() );
229         }
230         catch ( IOException e )
231         {
232             throw new MojoExecutionException( "Unable to create a directory...", e );
233         }
234     }
235 
236     
237 
238 
239 
240 
241 
242 
243 
244 
245     private void loadLicenseInfo( Map<String, ProjectLicenseInfo> configuredDepLicensesMap, File licenseConfigFile,
246                                   boolean previouslyDownloaded )
247         throws MojoExecutionException
248     {
249         FileInputStream fis = null;
250         try
251         {
252             fis = new FileInputStream( licenseConfigFile );
253             List<ProjectLicenseInfo> licensesList = LicenseSummaryReader.parseLicenseSummary( fis );
254             for ( ProjectLicenseInfo dep : licensesList )
255             {
256                 configuredDepLicensesMap.put( dep.getId(), dep );
257                 if ( previouslyDownloaded )
258                 {
259                     for ( License license : dep.getLicenses() )
260                     {
261                         
262                         downloadedLicenseURLs.add( license.getUrl() );
263                     }
264                 }
265             }
266         }
267         catch ( Exception e )
268         {
269             throw new MojoExecutionException( "Unable to parse license summary output file: " + licenseConfigFile, e );
270         }
271         finally
272         {
273             FileUtil.tryClose( fis );
274         }
275     }
276 
277     
278 
279 
280 
281 
282 
283     public String getArtifactProjectId( Artifact artifact )
284     {
285         return artifact.getGroupId() + ":" + artifact.getArtifactId();
286     }
287 
288     
289 
290 
291 
292 
293 
294     public ProjectLicenseInfo createDependencyProject( MavenProject depMavenProject )
295     {
296         ProjectLicenseInfo dependencyProject =
297             new ProjectLicenseInfo( depMavenProject.getGroupId(), depMavenProject.getArtifactId(),
298                                     depMavenProject.getVersion() );
299         List<?> licenses = depMavenProject.getLicenses();
300         for ( Object license : licenses )
301         {
302             dependencyProject.addLicense( (License) license );
303         }
304         return dependencyProject;
305     }
306 
307     
308 
309 
310 
311 
312 
313 
314 
315     private String getLicenseFileName( License license )
316         throws MalformedURLException
317     {
318         URL licenseUrl = new URL( license.getUrl() );
319         File licenseUrlFile = new File( licenseUrl.getPath() );
320         String licenseFileName = licenseUrlFile.getName();
321 
322         if ( license.getName() != null )
323         {
324             licenseFileName = license.getName() + " - " + licenseUrlFile.getName();
325         }
326 
327         
328         final String DEFAULT_EXTENSION = ".txt";
329         int extensionIndex = licenseFileName.lastIndexOf( "." );
330         if ( extensionIndex == -1 || extensionIndex > ( licenseFileName.length() - 3 ) )
331         {
332             
333             licenseFileName = licenseFileName + DEFAULT_EXTENSION;
334         }
335 
336         
337         licenseFileName = licenseFileName.toLowerCase();
338 
339         return licenseFileName;
340     }
341 
342     
343 
344 
345 
346 
347     private void downloadLicenses( ProjectLicenseInfo depProject )
348     {
349         getLog().debug( "Downloading license(s) for project " + depProject );
350 
351         List<License> licenses = depProject.getLicenses();
352 
353         if ( depProject.getLicenses() == null || depProject.getLicenses().isEmpty() )
354         {
355             if ( !quiet )
356             {
357                 getLog().warn( "No license information available for: " + depProject );
358             }
359             return;
360         }
361 
362         for ( License license : licenses )
363         {
364             try
365             {
366                 String licenseFileName = getLicenseFileName( license );
367 
368                 File licenseOutputFile = new File( licensesOutputDirectory, licenseFileName );
369                 if ( licenseOutputFile.exists() )
370                 {
371                     continue;
372                 }
373 
374                 if ( !downloadedLicenseURLs.contains( license.getUrl() ) )
375                 {
376                     LicenseDownloader.downloadLicense( license.getUrl(), licenseOutputFile );
377                     downloadedLicenseURLs.add( license.getUrl() );
378                 }
379             }
380             catch ( MalformedURLException e )
381             {
382                 if ( !quiet )
383                 {
384                     getLog().warn( "POM for dependency " + depProject.toString() + " has an invalid license URL: " +
385                                        license.getUrl() );
386                 }
387             }
388             catch ( FileNotFoundException e )
389             {
390                 if ( !quiet )
391                 {
392                     getLog().warn( "POM for dependency " + depProject.toString() +
393                                        " has a license URL that returns file not found: " + license.getUrl() );
394                 }
395             }
396             catch ( IOException e )
397             {
398                 getLog().warn( "Unable to retrieve license for dependency: " + depProject.toString() );
399                 getLog().warn( license.getUrl() );
400                 getLog().warn( e.getMessage() );
401             }
402 
403         }
404 
405     }
406 
407     public MavenProject getProject()
408     {
409         return project;
410     }
411 
412     public ArtifactRepository getLocalRepository()
413     {
414         return localRepository;
415     }
416 
417     public List getRemoteRepositories()
418     {
419         return remoteRepositories;
420     }
421 
422     
423 
424 
425     public boolean isIncludeTransitiveDependencies()
426     {
427         return includeTransitiveDependencies;
428     }
429 
430     
431 
432 
433     public List<String> getExcludedScopes()
434     {
435         String[] split = excludedScopes == null ? new String[0] : excludedScopes.split( "," );
436         return Arrays.asList( split );
437     }
438 
439     public void setExcludedScopes( String excludedScopes )
440     {
441         this.excludedScopes = excludedScopes;
442     }
443 
444     
445 
446 
447     public List<String> getIncludedScopes()
448     {
449         String[] split = includedScopes == null ? new String[0] : includedScopes.split( "," );
450         return Arrays.asList( split );
451     }
452 
453     public void setIncludedScopes( String includedScopes )
454     {
455         this.includedScopes = includedScopes;
456     }
457 
458     
459 
460     
461 
462 
463     public String getIncludedArtifacts()
464     {
465         return null;
466     }
467 
468     
469 
470     
471 
472 
473     public String getIncludedGroups()
474     {
475         return null;
476     }
477 
478     
479 
480     
481 
482 
483     public String getExcludedGroups()
484     {
485         return null;
486     }
487 
488     
489 
490     
491 
492 
493     public String getExcludedArtifacts()
494     {
495         return null;
496     }
497 
498     
499 
500 
501     public boolean isVerbose()
502     {
503         return getLog().isDebugEnabled();
504     }
505 }