r1776 - in trunk/src: main/java/org/nuiton/license/plugin site site/apt site/fr/apt
Author: tchemit Date: 2010-06-25 12:31:27 +0200 (Fri, 25 Jun 2010) New Revision: 1776 Url: http://nuiton.org/repositories/revision/maven-license-plugin/1776 Log: - Evolution #693: Improve Third-party generation (add a fallback file to push unknown license for dependencies) - Evolution #715: Introduce the aggregate-add-third-party mojo - Update docs Added: trunk/src/main/java/org/nuiton/license/plugin/AbstractAddThirdPartyMojo.java trunk/src/main/java/org/nuiton/license/plugin/AggregatorAddThirdPartyMojo.java trunk/src/main/java/org/nuiton/license/plugin/LicenseMap.java Modified: trunk/src/main/java/org/nuiton/license/plugin/AddThirdPartyMojo.java trunk/src/site/apt/index.apt trunk/src/site/apt/usage.apt trunk/src/site/fr/apt/index.apt trunk/src/site/fr/apt/usage.apt trunk/src/site/site_en.xml trunk/src/site/site_fr.xml Added: trunk/src/main/java/org/nuiton/license/plugin/AbstractAddThirdPartyMojo.java =================================================================== --- trunk/src/main/java/org/nuiton/license/plugin/AbstractAddThirdPartyMojo.java (rev 0) +++ trunk/src/main/java/org/nuiton/license/plugin/AbstractAddThirdPartyMojo.java 2010-06-25 10:31:27 UTC (rev 1776) @@ -0,0 +1,338 @@ +/* + * #%L + * Maven License Plugin + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * 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.nuiton.license.plugin; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.plugin.logging.Log; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.ProjectBuildingException; +import org.nuiton.io.SortedProperties; +import org.nuiton.plugin.PluginHelper; + +import java.io.File; +import java.io.IOException; +import java.util.SortedMap; +import java.util.SortedSet; +import java.util.TreeMap; + +/** + * Le goal pour copier le fichier THIRD-PARTY.txt (contenant les licenses de + * toutes les dependances du projet) dans le classpath (et le generer s'il + * n'existe pas). + * + * @author tchemit <chemit@codelutin.com> + * @since 2.3 + */ +public abstract class AbstractAddThirdPartyMojo extends AbstractLicenseMojo { + + /** + * Repertoire de sortie des classes (classpath). + * + * @parameter expression="${license.outputDirectory}" default-value="target/generated-sources/license" + * @required + * @since 2.3 + */ + protected File outputDirectory; + + /** + * Fichier ou ecrire les licences des dependances. + * + * @parameter expression="${license.thirdPartyFilename}" + * default-value="THIRD-PARTY.txt" + * @required + * @since 2.3 + */ + protected String thirdPartyFilename; + + /** + * A flag to use the missing licenses file to consolidate the THID-PARTY file. + * + * @parameter expression="${license.useMissingfile}" default-value="false" + * @since 2.3 + */ + protected boolean useMissingfile; + + /** + * The file where to fill the license for dependencies with unknwon license. + * + * @parameter expression="${license.missingFile}" default-value="src/license/THIRD-PARTY.properties" + * @since 1.0.0 + */ + protected File missingFile; + + /** + * The path of the bundled third party file to produce when + * {@link #generateBundle} is on. + * <p/> + * <b>Note:</b> This option is not available for {@code pom} module types. + * + * @parameter expression="${license.bundleThirdPartyPath}" default-value="META-INF/${project.artifactId}-THIRD-PARTY.txt" + * @since 2.3 + */ + protected String bundleThirdPartyPath; + + /** + * Un flag pour faire une copie nommé dans META-INF (prefixe avec le nom de + * l'artifact). + * + * @parameter expression="${license.generateBundle}" default-value="false" + * @since 2.3 + */ + protected boolean generateBundle; + + /** + * A flag to fail the build if at least one dependency was detected without a license. + * + * @parameter expression="${license.failIfWarning}" default-value="false" + * @since 2.3 + */ + protected boolean failIfWarning; + + + + private LicenseMap licenseMap; + + private SortedSet<MavenProject> unsafeDependencies; + + private File thirdPartyFile; + + private SortedProperties unsafeMappings; + + public static final String NO_DEPENDENCIES_MESSAGE = "the project has no dependencies."; + + private static SortedMap<String, MavenProject> artifactCache; + + public static SortedMap<String, MavenProject> getArtifactCache() { + if (artifactCache == null) { + artifactCache = new TreeMap<String, MavenProject>(); + } + return artifactCache; + } + + protected abstract LicenseMap createLicenseMap() throws ProjectBuildingException; + + protected abstract SortedProperties createUnsafeMapping() throws ProjectBuildingException, IOException; + + @Override + protected void init() throws Exception { + + Log log = getLog(); + + if (log.isDebugEnabled()) { + + // always be verbose in debug mode + setVerbose(true); + } + + File file = new File(getOutputDirectory(), getThirdPartyFilename()); + + setThirdPartyFile(file); + + licenseMap = createLicenseMap(); + licenseMap.setLog(log); + + unsafeDependencies = licenseMap.getUnsafeDependencies(); + + if (CollectionUtils.isEmpty(unsafeDependencies) || !isUseMissingfile()) { + + // no unsafe dependencies + // or user does not ask to generate missing file + // so no more thing to do + return; + } + + // load unsafeMapping + unsafeMappings = createUnsafeMapping(); + } + + public File getOutputDirectory() { + return outputDirectory; + } + + public String getThirdPartyFilename() { + return thirdPartyFilename; + } + + public String getBundleThirdPartyPath() { + return bundleThirdPartyPath; + } + + public boolean isGenerateBundle() { + return generateBundle; + } + + public boolean isFailIfWarning() { + return failIfWarning; + } + + public SortedSet<MavenProject> getUnsafeDependencies() { + return unsafeDependencies; + } + + public File getThirdPartyFile() { + return thirdPartyFile; + } + + public LicenseMap getLicenseMap() { + return licenseMap; + } + + public void setOutputDirectory(File outputDirectory) { + this.outputDirectory = outputDirectory; + } + + public void setThirdPartyFilename(String thirdPartyFilename) { + this.thirdPartyFilename = thirdPartyFilename; + } + + public void setBundleThirdPartyPath(String bundleThirdPartyPath) { + this.bundleThirdPartyPath = bundleThirdPartyPath; + } + + public void setGenerateBundle(boolean generateBundle) { + this.generateBundle = generateBundle; + } + + public void setThirdPartyFile(File thirdPartyFile) { + this.thirdPartyFile = thirdPartyFile; + } + + public boolean isUseMissingfile() { + return useMissingfile; + } + + public File getMissingFile() { + return missingFile; + } + + public void setUseMissingfile(boolean useMissingfile) { + this.useMissingfile = useMissingfile; + } + + public void setMissingFile(File missingFile) { + this.missingFile = missingFile; + } + + public void setFailIfWarning(boolean failIfWarning) { + this.failIfWarning = failIfWarning; + } + + public SortedProperties getUnsafeMappings() { + return unsafeMappings; + } + + protected boolean checkUnsafeDependencies() { + SortedSet<MavenProject> unsafeDependencies = getUnsafeDependencies(); + boolean unsafe = !CollectionUtils.isEmpty(unsafeDependencies); + if (unsafe) { + Log log = getLog(); + log.warn("There is " + unsafeDependencies.size() + " dependencies with no license :"); + for (MavenProject dep : unsafeDependencies) { + + // no license found for the dependency + log.warn(" - " + getArtifactId(dep.getArtifact())); + } + } + return unsafe; + } + + public static String getArtifactId(Artifact artifact) { + StringBuilder sb = new StringBuilder(); + sb.append(artifact.getGroupId()); + sb.append("--"); + sb.append(artifact.getArtifactId()); + sb.append("--"); + sb.append(artifact.getVersion()); + if (!StringUtils.isEmpty(artifact.getClassifier())) { + sb.append("--"); + sb.append(artifact.getClassifier()); + } + return sb.toString(); + } + + public static String getArtifactName(MavenProject project) { + StringBuilder sb = new StringBuilder(); + sb.append(project.getName()); + sb.append(" ("); + sb.append(project.getGroupId()); + sb.append(":"); + sb.append(project.getArtifactId()); + sb.append(":"); + sb.append(project.getVersion()); + sb.append(" - "); + String url = project.getUrl(); + sb.append(url == null ? "no url defined" : url); + sb.append(")"); + + return sb.toString(); + } + + protected void writeThirdPartyFile(boolean generate, boolean generateBundle) throws IOException { + + Log log = getLog(); + LicenseMap licenseMap = getLicenseMap(); + File target = getThirdPartyFile(); + + if (generate) { + StringBuilder sb = new StringBuilder(); + if (licenseMap.isEmpty()) { + sb.append(NO_DEPENDENCIES_MESSAGE); + } else { + sb.append("List of third-party dependencies grouped by " + + "their license type."); + for (String licenseName : licenseMap.keySet()) { + SortedSet<MavenProject> projects = licenseMap.get(licenseName); + sb.append("\n\n").append(licenseName).append(" : "); + + + for (MavenProject mavenProject : projects) { + String s = getArtifactName(mavenProject); + sb.append("\n * ").append(s); + } + } + } + String content = sb.toString(); + + log.info("writing third-party file to " + target); + if (isVerbose()) { + log.info(content); + } + + writeFile(target, content, getEncoding()); + } + + if (generateBundle) { + + // creates the bundled license file + File bundleTarget = + PluginHelper.getFile(getOutputDirectory(), getBundleThirdPartyPath()); + log.info("writing bundled third-party file to " + bundleTarget); + copyFile(target, bundleTarget); + } + } +} \ No newline at end of file Property changes on: trunk/src/main/java/org/nuiton/license/plugin/AbstractAddThirdPartyMojo.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Modified: trunk/src/main/java/org/nuiton/license/plugin/AddThirdPartyMojo.java =================================================================== --- trunk/src/main/java/org/nuiton/license/plugin/AddThirdPartyMojo.java 2010-06-20 21:41:45 UTC (rev 1775) +++ trunk/src/main/java/org/nuiton/license/plugin/AddThirdPartyMojo.java 2010-06-25 10:31:27 UTC (rev 1776) @@ -26,10 +26,8 @@ package org.nuiton.license.plugin; import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.lang.StringUtils; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.model.License; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugin.logging.Log; import org.apache.maven.project.MavenProject; @@ -40,14 +38,10 @@ import java.io.File; import java.io.FileWriter; -import java.util.Arrays; -import java.util.Comparator; +import java.io.IOException; import java.util.List; import java.util.Set; -import java.util.SortedMap; import java.util.SortedSet; -import java.util.TreeMap; -import java.util.TreeSet; /** * Le goal pour copier le fichier THIRD-PARTY.txt (contenant les licenses de @@ -61,66 +55,9 @@ * @requiresProject true * @since 2.2 (was previously {@code AddThirdPartyFileMojo}). */ -public class AddThirdPartyMojo extends AbstractLicenseMojo { +public class AddThirdPartyMojo extends AbstractAddThirdPartyMojo { - private static final String unknownLicenseMessage = "Unknown license"; - /** - * Repertoire de sortie des classes (classpath). - * - * @parameter expression="${license.outputDirectory}" default-value="target/generated-sources/license" - * @required - * @since 1.0.0 - */ - protected File outputDirectory; - - /** - * Fichier ou ecrire les licences des dependances. - * - * @parameter expression="${license.thirdPartyFilename}" - * default-value="THIRD-PARTY.txt" - * @required - * @since 1.0.0 - */ - protected String thirdPartyFilename; - - /** - * The path of the bundled third party file to produce when - * {@link #generateBundle} is on. - * <p/> - * <b>Note:</b> This option is not available for {@code pom} module types. - * - * @parameter expression="${license.bundleThirdPartyPath}" default-value="META-INF/${project.artifactId}-THIRD-PARTY.txt" - * @since 2.2 - */ - protected String bundleThirdPartyPath; - - /** - * The file where to fill the license for dependencies with unknwon license. - * - * @parameter expression="${license.missingFile}" default-value="src/license/THIRD-PARTY.properties" - * @since 1.0.0 - */ - protected File missingFile; - - /** - * Un flag pour faire une copie nommé dans META-INF (prefixe avec le nom de - * l'artifact). - * - * @parameter expression="${license.generateBundle}" default-value="false" - * @since 1.0.0 - */ - protected boolean generateBundle; - - /** - * A flag to generate or update the missing licenses file. - * - * @parameter expression="${license.generateMissing}" default-value="true" - * @since 2.3 - */ - protected boolean generateMissing; - - /** * Un flag pour forcer la generation. * * @parameter expression="${license.force}" default-value="false" @@ -129,22 +66,6 @@ protected boolean force; /** - * A flag to fail the build if at least one dependency was detected without a license. - * - * @parameter expression="${license.failIfWarning}" default-value="false" - * @since 2.3 - */ - protected boolean failIfWarning; - - /** - * Un flag pour conserver un backup des fichiers modifies. - * - * @parameter expression="${license.keepBackup}" default-value="false" - * @since 1.0.0 - */ - protected boolean keepBackup; - - /** * Local Repository. * * @parameter expression="${localRepository}" @@ -174,51 +95,26 @@ */ protected MavenProjectBuilder mavenProjectBuilder; - private File thirdPartyFile; - - private LicenseMap licenseMap; - - private SortedSet<MavenProject> unsafeDependencies; - - private SortedProperties unsafeMappings; - private boolean doGenerate; private boolean doGenerateBundle; private boolean doGenerateMissing; - private static SortedMap<String, MavenProject> artifactCache; - - public static SortedMap<String, MavenProject> getArtifactCache() { - if (artifactCache == null) { - artifactCache = new TreeMap<String, MavenProject>(); - } - return artifactCache; - } - - public static final String NO_DEPENDENCIES_MESSAGE = "the project has no dependencies."; - @Override protected boolean checkPackaging() { return rejectPackaging(Packaging.pom); } @Override - protected void init() throws Exception { + protected LicenseMap createLicenseMap() throws ProjectBuildingException { Log log = getLog(); - if (log.isDebugEnabled()) { - // always be verbose in debug mode - setVerbose(true); - } + LicenseMap licenseMap = new LicenseMap(); + licenseMap.setLog(log); - licenseMap = new LicenseMap(); + File file = getThirdPartyFile(); - File file = new File(getOutputDirectory(), getThirdPartyFilename()); - - setThirdPartyFile(file); - setDoGenerate(isForce() || !file.exists() || !isFileNewerThanPomFile(file)); if (isGenerateBundle()) { @@ -237,9 +133,7 @@ } if (!isDoGenerate() && !isDoGenerateBundle()) { - - // nothing to do - return; + return licenseMap; } // build the license map for the dependencies of the project @@ -257,90 +151,23 @@ MavenProject project = addArtifact(id, artifact); - addLicense(project, project.getLicenses()); + licenseMap.addLicense(project, project.getLicenses()); } - // get unsafe dependencies (says with no license) - unsafeDependencies = licenseMap.get(getUnknownLicenseMessage()); + return licenseMap; + } - if (CollectionUtils.isEmpty(unsafeDependencies)) { - // no unsafe dependencies, so no need to generate missing file - setDoGenerateMissing(false); - return; - } + @Override + protected SortedProperties createUnsafeMapping() throws ProjectBuildingException, IOException { + SortedProperties unsafeMappings = getLicenseMap().loadUnsafeMapping(getEncoding(), getMissingFile()); - if (log.isDebugEnabled()) { - log.debug("There is " + unsafeDependencies.size() + " dependencies with no license from poms : "); - for (MavenProject dep : unsafeDependencies) { + SortedSet<MavenProject> unsafeDependencies = getUnsafeDependencies(); - // no license found for the dependency - log.debug(" - " + getArtifactId(dep.getArtifact())); - } - } + setDoGenerateMissing(!CollectionUtils.isEmpty(unsafeDependencies) && + isUseMissingfile()); - if (!isGenerateMissing()) { - - // user does not ask to generate missing file - // so no more thing to do - return; - } - - unsafeMappings = new SortedProperties(getEncoding()); - - // there is some unsafe dependencies - if (missingFile.exists()) { - - // load the missing file - unsafeMappings.load(missingFile); - } - - // push back loaded dependencies - for (Object o : unsafeMappings.keySet()) { - String id = (String) o; - - MavenProject project = getArtifactCache().get(id); - if (project == null) { - log.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 unsafe dependencies, so no need to generate missing file - setDoGenerateMissing(false); - - // no more unknown license in map - licenseMap.remove(getUnknownLicenseMessage()); - return; - } - - // mark to regenerate the file (if anything has changed) - setDoGenerateMissing(true); - - for (MavenProject project : unsafeDependencies) { - String id = getArtifactId(project.getArtifact()); - unsafeMappings.setProperty(id, ""); - } + return unsafeMappings; } @Override @@ -358,111 +185,51 @@ @Override protected void doAction() throws Exception { - Log log = getLog(); + boolean unsafe = checkUnsafeDependencies(); - File target = getThirdPartyFile(); - File output = getOutputDirectory(); + writeThirdPartyFile(isDoGenerate(), isDoGenerateBundle()); - boolean unsafe = !CollectionUtils.isEmpty(unsafeDependencies); - if (unsafe) { - - log.warn("There is " + unsafeDependencies.size() + " dependencies with no license :"); - for (MavenProject dep : unsafeDependencies) { - - // no license found for the dependency - log.warn(" - " + getArtifactId(dep.getArtifact())); - } - } - if (isDoGenerate()) { - - // build thirdPartyFileContent - String content = buildThirdPartyFilecontent(); - - if (isVerbose()) { - log.info("writing third-party file : " + target + "\n" + content); - } - - if (isKeepBackup() && target.exists()) { - if (isVerbose()) { - log.info("backup " + target); - } - backupFile(target); - } - writeFile(target, content, getEncoding()); - } - - if (isDoGenerateBundle()) { - - // creates the bundled license file - File bundleTarget = - PluginHelper.getFile(output, getBundleThirdPartyPath()); - copyFile(target, bundleTarget); - } - if (isDoGenerateMissing()) { - File file = getMissingFile(); - createDirectoryIfNecessary(file.getParentFile()); - if (isVerbose()) { - log.info("regenerate missing license file " + file); - } - FileWriter writer = new FileWriter(file); - try { - StringBuilder sb = new StringBuilder(" Generated by " + getClass().getName()); - Set<String> licenses = licenseMap.keySet(); - if (!licenses.isEmpty()) { - sb.append("\n-------------------------------------------------------------------------------"); - sb.append("\n Already used licenses in project :"); - for (String license : licenses) { - if (getUnknownLicenseMessage().equals(license)) { - continue; - } - sb.append("\n - ").append(license); - } - } - sb.append("\n-------------------------------------------------------------------------------"); - sb.append("\n Please fill the missing licenses for dependencies :\n\n"); - unsafeMappings.store(writer, sb.toString()); - } finally { - writer.close(); - } + writeMissingFile(); } if (unsafe && isFailIfWarning()) { throw new MojoFailureException("There is some dependencies with no license, please fill the file " + getMissingFile()); } - addResourceDir(output, "**/*.txt"); + addResourceDir(getOutputDirectory(), "**/*.txt"); } + protected void writeMissingFile() throws IOException { - protected void addLicense(MavenProject project, - List<?> licenses) throws ProjectBuildingException { + Log log = getLog(); - if (Artifact.SCOPE_SYSTEM.equals(project.getArtifact().getScope())) { - // do NOT treate system dependency - return; + LicenseMap licenseMap = getLicenseMap(); + File file = getMissingFile(); + createDirectoryIfNecessary(file.getParentFile()); + if (isVerbose()) { + log.info("regenerate missing license file " + file); } - - if (CollectionUtils.isEmpty(licenses)) { - - // no license found for the dependency - licenseMap.put(getUnknownLicenseMessage(), project); - return; - } - - for (Object o : licenses) { - if (o == null) { - getLog().warn("could not acquire the license for " + getArtifactId(project.getArtifact())); - continue; + FileWriter writer = new FileWriter(file); + try { + StringBuilder sb = new StringBuilder(" Generated by " + getClass().getName()); + Set<String> licenses = licenseMap.keySet(); + if (!licenses.isEmpty()) { + sb.append("\n-------------------------------------------------------------------------------"); + sb.append("\n Already used licenses in project :"); + for (String license : licenses) { + if (!LicenseMap.getUnknownLicenseMessage().equals(license)) { + sb.append("\n - ").append(license); + } + } } - License license = (License) o; - String licenseKey = license.getName(); - if (license.getName() == null) { - licenseKey = license.getUrl(); - } - licenseMap.put(licenseKey, project); + sb.append("\n-------------------------------------------------------------------------------"); + sb.append("\n Please fill the missing licenses for dependencies :\n\n"); + getUnsafeMappings().store(writer, sb.toString()); + } finally { + writer.close(); } } @@ -492,156 +259,23 @@ return project; } - protected String getArtifactId(Artifact artifact) { - StringBuilder sb = new StringBuilder(); - sb.append(artifact.getGroupId()); - sb.append("--"); - sb.append(artifact.getArtifactId()); - sb.append("--"); - sb.append(artifact.getVersion()); - if (!StringUtils.isEmpty(artifact.getClassifier())) { - sb.append("--"); - sb.append(artifact.getClassifier()); - } - return sb.toString(); - } - protected String getArtifactName(MavenProject project) { - StringBuilder sb = new StringBuilder(); - sb.append(project.getName()); - sb.append(" ("); - sb.append(project.getGroupId()); - sb.append(":"); - sb.append(project.getArtifactId()); - sb.append(":"); - sb.append(project.getVersion()); - sb.append(" - "); - String url = project.getUrl(); - sb.append(url == null ? "no url defined" : url); - sb.append(")"); - - return sb.toString(); - } - - protected String buildThirdPartyFilecontent() { - StringBuilder sb = new StringBuilder(); - if (licenseMap.isEmpty()) { - sb.append(NO_DEPENDENCIES_MESSAGE); - } else { - sb.append("List of third-party dependencies grouped by " + - "their license type."); - for (String licenseName : licenseMap.keySet()) { - SortedSet<MavenProject> projects = licenseMap.get(licenseName); - sb.append("\n\n").append(licenseName).append(" : "); - - - for (MavenProject mavenProject : projects) { - String s = getArtifactName(mavenProject); - sb.append("\n * ").append(s); - } - } - } - String content = sb.toString(); - if (getLog().isDebugEnabled()) { - getLog().debug("third-party file content :\n" + content); - } - return content; - } - - - public static String getUnknownLicenseMessage() { - return unknownLicenseMessage; - } - - public String getThirdPartyFilename() { - return thirdPartyFilename; - } - - public File getOutputDirectory() { - return outputDirectory; - } - public boolean isForce() { return force; } - public boolean isKeepBackup() { - return keepBackup; - } - - public boolean isGenerateBundle() { - return generateBundle; - } - public boolean isDoGenerate() { return doGenerate; } - public String getBundleThirdPartyPath() { - return bundleThirdPartyPath; - } - - - public File getThirdPartyFile() { - return thirdPartyFile; - } - - public File getMissingFile() { - return missingFile; - } - - public boolean isGenerateMissing() { - return generateMissing; - } - - public boolean isFailIfWarning() { - return failIfWarning; - } - - public void setThirdPartyFilename(String thirdPartyFilename) { - this.thirdPartyFilename = thirdPartyFilename; - } - public void setForce(boolean force) { this.force = force; } - public void setOutputDirectory(File outputDirectory) { - this.outputDirectory = outputDirectory; - } - - public void setKeepBackup(boolean keepBackup) { - this.keepBackup = keepBackup; - } - - public void setGenerateBundle(boolean generateBundle) { - this.generateBundle = generateBundle; - } - - public void setBundleThirdPartyPath(String bundleThirdPartyPath) { - this.bundleThirdPartyPath = bundleThirdPartyPath; - } - public void setDoGenerate(boolean doGenerate) { this.doGenerate = doGenerate; } - public void setThirdPartyFile(File thirdPartyFile) { - this.thirdPartyFile = thirdPartyFile; - } - - public void setMissingFile(File missingFile) { - this.missingFile = missingFile; - } - - public void setGenerateMissing(boolean generateMissing) { - this.generateMissing = generateMissing; - } - - public void setFailIfWarning(boolean failIfWarning) { - this.failIfWarning = failIfWarning; - } - public boolean isDoGenerateBundle() { return doGenerateBundle; } @@ -658,29 +292,4 @@ this.doGenerateMissing = doGenerateMissing; } - protected class LicenseMap extends TreeMap<String, SortedSet<MavenProject>> { - - private static final long serialVersionUID = 864199843545688069L; - - 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>(new Comparator<MavenProject>() { - @Override - public int compare(MavenProject o1, MavenProject o2) { - - String id1 = getArtifactId(o1.getArtifact()); - String id2 = getArtifactId(o2.getArtifact()); - return id1.compareTo(id2); - } - }); - } - if (getLog().isDebugEnabled()) { - getLog().debug("key:" + key + ",value: " + value); - } - valueList.add(value); - return put(key, valueList); - } - } } \ No newline at end of file Added: trunk/src/main/java/org/nuiton/license/plugin/AggregatorAddThirdPartyMojo.java =================================================================== --- trunk/src/main/java/org/nuiton/license/plugin/AggregatorAddThirdPartyMojo.java (rev 0) +++ trunk/src/main/java/org/nuiton/license/plugin/AggregatorAddThirdPartyMojo.java 2010-06-25 10:31:27 UTC (rev 1776) @@ -0,0 +1,154 @@ +/* + * #%L + * Maven License Plugin + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * 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.nuiton.license.plugin; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.logging.Log; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.ProjectBuildingException; +import org.nuiton.io.SortedProperties; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.SortedMap; +import java.util.SortedSet; + +/** + * This aggregator goal (will be executed only once and only on pom projects) + * executed the {@code add-third-party} on all his modules (in a parellel build cycle) + * then aggreates all the third-party files in final one in the pom project. + * + * @author tchemit <chemit@codelutin.com> + * @goal aggregate-add-third-party + * @phase generate-resources + * @requiresProject true + * @aggregator true + * @execute goal="add-third-party" + * @since 2.3 + */ +public class AggregatorAddThirdPartyMojo extends AbstractAddThirdPartyMojo { + + /** + * The projects in the reactor. + * + * @parameter expression="${reactorProjects}" + * @readonly + * @required + * @since 2.3 + */ + protected List reactorProjects; + + @Override + protected boolean checkPackaging() { + return acceptPackaging(Packaging.pom); + } + + @Override + protected LicenseMap createLicenseMap() throws ProjectBuildingException { + Log log = getLog(); + + LicenseMap licenseMap = new LicenseMap(); + licenseMap.setLog(log); + + SortedMap<String, MavenProject> artifacts = getArtifactCache(); + for (MavenProject project : artifacts.values()) { + licenseMap.addLicense(project, project.getLicenses()); + } + return licenseMap; + } + + @Override + protected SortedProperties createUnsafeMapping() throws ProjectBuildingException, IOException { + + String path = getMissingFile().getAbsolutePath().substring(getProject().getBasedir().getAbsolutePath().length() + 1); + + if (isVerbose()) { + getLog().info("will use missing file path : " + path); + } + + SortedProperties unsafeMappings = new SortedProperties(getEncoding()); + + LicenseMap licenseMap = getLicenseMap(); + + for (Object o : reactorProjects) { + MavenProject p = (MavenProject) o; + + File file = new File(p.getBasedir(), path); + + if (file.exists()) { + + if (isVerbose()) { + getLog().info("will load missing file : " + file); + } + + SortedProperties tmp = licenseMap.loadUnsafeMapping(getEncoding(), file); + unsafeMappings.putAll(tmp); + } + + SortedSet<MavenProject> unsafes = licenseMap.getUnsafeDependencies(); + if (CollectionUtils.isEmpty(unsafes)) { + // no more unsafe dependencies, can break + break; + } + } + return unsafeMappings; + } + + @Override + protected void doAction() throws Exception { + Log log = getLog(); + + if (isVerbose()) { + log.info("After executing on " + reactorProjects.size() + " project(s)"); + } + SortedMap<String, MavenProject> artifacts = getArtifactCache(); + + LicenseMap licenseMap = getLicenseMap(); + + getLog().info(artifacts.size() + " detected artifact(s)."); + if (isVerbose()) { + for (String id : artifacts.keySet()) { + getLog().info(" - " + id); + } + } + getLog().info(licenseMap.size() + " detected license(s)."); + if (isVerbose()) { + for (String id : licenseMap.keySet()) { + getLog().info(" - " + id); + } + } + boolean unsafe = checkUnsafeDependencies(); + + writeThirdPartyFile(true, isGenerateBundle()); + + if (unsafe && isFailIfWarning()) { + throw new MojoFailureException("There is some dependencies with no license, please review the modules."); + } + } + +} \ No newline at end of file Property changes on: trunk/src/main/java/org/nuiton/license/plugin/AggregatorAddThirdPartyMojo.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: trunk/src/main/java/org/nuiton/license/plugin/LicenseMap.java =================================================================== --- trunk/src/main/java/org/nuiton/license/plugin/LicenseMap.java (rev 0) +++ trunk/src/main/java/org/nuiton/license/plugin/LicenseMap.java 2010-06-25 10:31:27 UTC (rev 1776) @@ -0,0 +1,201 @@ +/* + * #%L + * Maven License Plugin + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * 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.nuiton.license.plugin; + +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 org.nuiton.io.SortedProperties; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.SortedSet; +import java.util.TreeMap; +import java.util.TreeSet; + +/** + * Map of artifacts (stub in mavenproject) group by their license. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.3 + */ +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) throws ProjectBuildingException { + + 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) { + if (o == null) { + getLog().warn("could not acquire the license for " + AbstractAddThirdPartyMojo.getArtifactId(project.getArtifact())); + continue; + } + License license = (License) o; + String licenseKey = license.getName(); + if (license.getName() == null) { + licenseKey = license.getUrl(); + } + 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()) { + log.debug("There is " + unsafeDependencies.size() + " dependencies with no license from poms : "); + for (MavenProject dep : unsafeDependencies) { + + // no license found for the dependency + log.debug(" - " + AbstractAddThirdPartyMojo.getArtifactId(dep.getArtifact())); + } + } + + return unsafeDependencies; + } + + protected SortedProperties loadUnsafeMapping(String encoding, File missingFile) throws IOException, ProjectBuildingException { + + + SortedSet<MavenProject> unsafeDependencies = getUnsafeDependencies(); + + SortedProperties unsafeMappings = new SortedProperties(encoding); + + // there is some unsafe dependencies + if (missingFile.exists()) { + + // load the missing file + unsafeMappings.load(missingFile); + } + + // push back loaded dependencies + for (Object o : unsafeMappings.keySet()) { + String id = (String) o; + + MavenProject project = AbstractAddThirdPartyMojo.getArtifactCache().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 = AbstractAddThirdPartyMojo.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>(new Comparator<MavenProject>() { + @Override + public int compare(MavenProject o1, MavenProject o2) { + + String id1 = AbstractAddThirdPartyMojo.getArtifactId(o1.getArtifact()); + String id2 = AbstractAddThirdPartyMojo.getArtifactId(o2.getArtifact()); + return id1.compareTo(id2); + } + }); + } + if (getLog().isDebugEnabled()) { + getLog().debug("key:" + key + ",value: " + value); + } + valueList.add(value); + return put(key, valueList); + } + + public static String getUnknownLicenseMessage() { + return unknownLicenseMessage; + } +} Property changes on: trunk/src/main/java/org/nuiton/license/plugin/LicenseMap.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Modified: trunk/src/site/apt/index.apt =================================================================== --- trunk/src/site/apt/index.apt 2010-06-20 21:41:45 UTC (rev 1775) +++ trunk/src/site/apt/index.apt 2010-06-25 10:31:27 UTC (rev 1776) @@ -31,6 +31,7 @@ The Maven License Plugin is used to deal with license stuff on a maven project. * NOTE + The process tags are separated by space otherwise plugin can NOT update header of this file! @@ -88,6 +89,8 @@ * {{{./add-third-party-mojo.html}add-third-party}} creates the THIRD-PARTY.txt in the build. + * {{{./aggregate-add-third-party-mojo.html}aggregate-add-third-party}} creates the THIRD-PARTY.txt of an pom project using the THIRD-PARTY file of all his modules. + * {{{./comment-style-list-mojo.html}comment-style-list}} display list of available comment style header (since 2.1). * {{{./license-list-mojo.html}license-list}} display list of available licenses. Modified: trunk/src/site/apt/usage.apt =================================================================== --- trunk/src/site/apt/usage.apt 2010-06-20 21:41:45 UTC (rev 1775) +++ trunk/src/site/apt/usage.apt 2010-06-25 10:31:27 UTC (rev 1776) @@ -49,8 +49,23 @@ This goal build the THIRD-PARTY.txt file and add it in build. + <Since version 2.3>, we can consolidate the generated file by filling another + file (the <<missing file>>) for dependencies without license. + + <Note:> This mojo has not effect on a <<pom>> project. + for full detail see {{{./add-third-party-mojo.html}detail page}}. + +* aggregate-add-third-party goal + + This goal build the THIRD-PARTY.txt file on a multi-module project from + the dependencies of all his modules. + + <Note:> This mojo has only effect on a <<pom>> project. + + for full detail see {{{./aggregate-add-third-party-mojo.html}detail page}}. + Get informations * license-list goal Modified: trunk/src/site/fr/apt/index.apt =================================================================== --- trunk/src/site/fr/apt/index.apt 2010-06-20 21:41:45 UTC (rev 1775) +++ trunk/src/site/fr/apt/index.apt 2010-06-25 10:31:27 UTC (rev 1776) @@ -32,6 +32,7 @@ Maven. * NOTE + Dans la documentation, les tags de process sont séparés par des espaces où le plugin ne pourrait PAS gérer la license de ces fichiers ! @@ -95,6 +96,11 @@ * {{{./add-third-party-mojo.html}add-third-party}} crée le fichier <THIRD-PARTY.txt> dans le build. + + * {{{./aggregate-add-third-party-mojo.html}aggregate-add-third-party}} + crée le fichier THIRD-PARTY.txt pour un projet de type <<pom>> en utilisant + les THIRD-PARTY de ses modules. + * {{{./license-list-mojo.html}license-list}} Affiche la liste des licenses disponibles. Modified: trunk/src/site/fr/apt/usage.apt =================================================================== --- trunk/src/site/fr/apt/usage.apt 2010-06-20 21:41:45 UTC (rev 1775) +++ trunk/src/site/fr/apt/usage.apt 2010-06-25 10:31:27 UTC (rev 1776) @@ -51,9 +51,24 @@ Ce goal construit le fichier THIRD-PARTY.txt et l'ajoute au build. + <Depuis la version 2.3>, on peut consolider le fichier généré en remplissant + un fichier pour les dépendances sans license. + + <Note:> Ce goal n'a pas d'effet sur un projet de type <<pom>>. + Pour plus de détails, référez-vous à {{{./add-third-party-mojo.html}la page de détail}}. +* aggregate-add-third-party goal + + Ce goal construit le fichier THIRD-PARTY.txt d'un projet multi-module + à partir de toutes les dépendences des modules du projet. + + <Note:> Ce goal n'a d'effet que sur un projet de type <<pom>>. + + Pour plus de détails, référez-vous à + {{{./aggregate-add-third-party-mojo.html}la page de détail}}. + Obtenir des informations * license-list goal Modified: trunk/src/site/site_en.xml =================================================================== --- trunk/src/site/site_en.xml 2010-06-20 21:41:45 UTC (rev 1775) +++ trunk/src/site/site_en.xml 2010-06-25 10:31:27 UTC (rev 1776) @@ -63,6 +63,7 @@ <item name="update-project-license" href="update-project-license-mojo.html"/> <item name="update-file-header" href="update-file-header-mojo.html"/> <item name="add-third-party" href="add-third-party-mojo.html"/> + <item name="aggregate-add-third-party" href="aggregate-add-third-party-mojo.html"/> </item> <item name="Get information" href="usage.html#get-information"> <item name="license-list" href="license-list-mojo.html"/> Modified: trunk/src/site/site_fr.xml =================================================================== --- trunk/src/site/site_fr.xml 2010-06-20 21:41:45 UTC (rev 1775) +++ trunk/src/site/site_fr.xml 2010-06-25 10:31:27 UTC (rev 1776) @@ -62,6 +62,7 @@ <item name="update-project-license" href="update-project-license-mojo.html"/> <item name="update-file-header" href="update-file-header-mojo.html"/> <item name="add-third-party" href="add-third-party-mojo.html"/> + <item name="aggregate-add-third-party" href="aggregate-add-third-party-mojo.html"/> </item> <item name="Obtenir des informations" href="usage.html#obtenir-des-informations"> <item name="license-list" href="license-list-mojo.html"/>
participants (1)
-
tchemit@users.nuiton.org