/* * #%L * License Maven Plugin * * $Id$ * $HeadURL$ * %% * Copyright (C) 2008 - 2011 CodeLutin, Codehaus, Tony Chemit * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Lesser Public License for more details. * * You should have received a copy of the GNU General Lesser Public * License along with this program. If not, see * <http://www.gnu.org/licenses/lgpl-3.0.html>. * #L% */ package org.codehaus.mojo.license; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.apache.maven.artifact.Artifact; import org.apache.maven.model.License; import org.apache.maven.plugin.logging.Log; import org.apache.maven.project.MavenProject; import org.apache.maven.project.ProjectBuildingException; import java.io.File; import java.io.IOException; import java.util.*; /** * Map of artifacts (stub in mavenproject) group by their license. * * @author tchemit <chemit@codelutin.com> * @since 1.0 */ public class LicenseMap extends TreeMap<String, SortedSet<MavenProject>> { private static final long serialVersionUID = 864199843545688069L; private transient Log log; public static final String unknownLicenseMessage = "Unknown license"; public LicenseMap() { } public void setLog( Log log ) { this.log = log; } public Log getLog() { return log; } public void addLicense( MavenProject project, List<?> licenses ) { if ( Artifact.SCOPE_SYSTEM.equals( project.getArtifact().getScope() ) ) { // do NOT treate system dependency return; } if ( CollectionUtils.isEmpty( licenses ) ) { // no license found for the dependency put( getUnknownLicenseMessage(), project ); return; } for ( Object o : licenses ) { String id; id = ArtifactHelper.getArtifactId( project.getArtifact() ); if ( o == null ) { getLog().warn( "could not acquire the license for " + id ); continue; } License license = (License) o; String licenseKey = license.getName(); // tchemit 2010-08-29 Ano #816 Check if the License object is well formed if ( StringUtils.isEmpty( license.getName() ) ) { getLog().warn( "No license name defined for " + id ); licenseKey = license.getUrl(); } if ( StringUtils.isEmpty( licenseKey ) ) { getLog().warn( "No license url defined for " + id ); licenseKey = getUnknownLicenseMessage(); } put( licenseKey, project ); } } public SortedSet<MavenProject> getUnsafeDependencies() { Log log = getLog(); // get unsafe dependencies (says with no license) SortedSet<MavenProject> unsafeDependencies = get( getUnknownLicenseMessage() ); if ( log.isDebugEnabled() ) { if ( CollectionUtils.isEmpty( unsafeDependencies ) ) { log.debug( "There is no dependency with no license from poms." ); } else { log.debug( "There is " + unsafeDependencies.size() + " dependencies with no license from poms : " ); for ( MavenProject dep : unsafeDependencies ) { // no license found for the dependency log.debug( " - " + ArtifactHelper.getArtifactId( dep.getArtifact() ) ); } } } return unsafeDependencies; } protected SortedProperties loadUnsafeMapping( SortedMap<String, MavenProject> artifactCache, String encoding, File missingFile ) throws IOException, ProjectBuildingException { SortedSet<MavenProject> unsafeDependencies = getUnsafeDependencies(); SortedProperties unsafeMappings = new SortedProperties( encoding ); // there is some unsafe dependencies if ( missingFile.exists() ) { getLog().info( "Load missing file " + missingFile ); // load the missing file unsafeMappings.load( missingFile ); } // get from the missing file, all unknown dependencies List<String> unknownDependenciesId = new ArrayList<String>(); // migrate unsafe mapping (before version 3.0 we do not have the type of // dependency in the missing file, now we must deal with it, so check it List<String> migrateId = new ArrayList<String>(); // SortedMap<String, MavenProject> artifactCache = AbstractAddThirdPartyMojo.getArtifactCache(); for ( Object o : unsafeMappings.keySet() ) { String id = (String) o; MavenProject project = artifactCache.get( id ); if ( project == null ) { // try with the --jar type project = artifactCache.get( id + "--jar" ); if ( project == null ) { // now we are sure this is a unknown dependency unknownDependenciesId.add( id ); } else { // this dependency must be migrated migrateId.add( id ); } } } if ( !unknownDependenciesId.isEmpty() ) { // there is some unknown dependencies in the missing file, remove them for ( String id : unknownDependenciesId ) { getLog().warn( "dependency [" + id + "] does not exists in project, remove it from the missing file." ); unsafeMappings.remove( id ); } unknownDependenciesId.clear(); } if ( !migrateId.isEmpty() ) { // there is some dependencies to migrate in the missing file for ( String id : migrateId ) { String newId = id + "--jar"; getLog().info( "Migrate " + id + " to " + newId + " in the missing file." ); Object value = unsafeMappings.get( id ); unsafeMappings.remove( id ); unsafeMappings.put( newId, value ); } migrateId.clear(); } // push back loaded dependencies for ( Object o : unsafeMappings.keySet() ) { String id = (String) o; MavenProject project = artifactCache.get( id ); if ( project == null ) { getLog().warn( "dependency [" + id + "] does not exists in project." ); continue; } String license = (String) unsafeMappings.get( id ); if ( StringUtils.isEmpty( license ) ) { // empty license means not fill, skip it continue; } // add license in map License l = new License(); l.setName( license.trim() ); l.setUrl( license.trim() ); // add license addLicense( project, Arrays.asList( l ) ); // remove unknown license unsafeDependencies.remove( project ); } if ( unsafeDependencies.isEmpty() ) { // no more unknown license in map remove( getUnknownLicenseMessage() ); } else { // add a "with no value license" for missing dependencies for ( MavenProject project : unsafeDependencies ) { String id = ArtifactHelper.getArtifactId( project.getArtifact() ); unsafeMappings.setProperty( id, "" ); } } return unsafeMappings; } public SortedSet<MavenProject> put( String key, MavenProject value ) { // handle multiple values as a set to avoid duplicates SortedSet<MavenProject> valueList = get( key ); if ( valueList == null ) { valueList = new TreeSet<MavenProject>( ArtifactHelper.getProjectComparator() ); } if ( getLog().isDebugEnabled() ) { getLog().debug( "key:" + key + ",value: " + value ); } valueList.add( value ); return put( key, valueList ); } public SortedMap<MavenProject, String[]> toDependencyMap() { SortedMap<MavenProject, Set<String>> tmp = new TreeMap<MavenProject, Set<String>>( ArtifactHelper.getProjectComparator() ); for ( Map.Entry<String, SortedSet<MavenProject>> entry : entrySet() ) { String license = entry.getKey(); SortedSet<MavenProject> set = entry.getValue(); for ( MavenProject p : set ) { Set<String> list = tmp.get( p ); if ( list == null ) { list = new HashSet<String>(); tmp.put( p, list ); } list.add( license ); } } SortedMap<MavenProject, String[]> result = new TreeMap<MavenProject, String[]>( ArtifactHelper.getProjectComparator() ); for ( Map.Entry<MavenProject, Set<String>> entry : tmp.entrySet() ) { List<String> value = new ArrayList<String>( entry.getValue() ); Collections.sort( value ); result.put( entry.getKey(), value.toArray( new String[value.size()] ) ); } tmp.clear(); return result; } public static String getUnknownLicenseMessage() { return unknownLicenseMessage; } public void mergeLicenses( String... licenses ) { if ( licenses.length == 0 ) { return; } String mainLicense = licenses[0].trim(); SortedSet<MavenProject> mainSet = get( mainLicense ); if ( mainSet == null ) { getLog().warn( "No license [" + mainLicense + "] found, will create it." ); mainSet = new TreeSet<MavenProject>( ArtifactHelper.getProjectComparator() ); put( mainLicense, mainSet ); } int size = licenses.length; for ( int i = 1; i < size; i++ ) { String license = licenses[i].trim(); SortedSet<MavenProject> set = get( license ); if ( set == null ) { getLog().warn( "No license [" + license + "] found, skip this merge." ); continue; } getLog().info( "Merge license [" + license + "] (" + set.size() + " depedencies)." ); mainSet.addAll( set ); set.clear(); remove( license ); } } }