All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.linuxstuff.mojo.licensing.AbstractLicensingMojo Maven / Gradle / Ivy

There is a newer version: 1.7.11
Show newest version
package org.linuxstuff.mojo.licensing;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.model.License;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.resource.ResourceManager;
import org.linuxstuff.mojo.licensing.model.ArtifactWithLicenses;
import org.linuxstuff.mojo.licensing.model.CoalescedLicense;
import org.linuxstuff.mojo.licensing.model.LicensingRequirements;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.StaxDriver;

/**
 * Some basic plumbing for licensing mojos. I've borrowed
 * {@code MavenProjectDependenciesConfigurator} from the license plugin since it
 * rocks.
 * 
 * @see CheckMojo
 * @see CollectReportsMojo
 */
abstract public class AbstractLicensingMojo extends AbstractMojo implements MavenProjectDependenciesConfigurator {

	/**
	 * Used to read in the licensing-requirements from the plugin's classpath.
	 * 
	 * @plexus.requirement role="org.codehaus.plexus.resource.ResourceManager"
	 *                     role-hint="default"
	 * @component
	 * @required
	 * @readonly
	 * @since 1.0
	 */
	protected ResourceManager locator;

	/**
	 * Local Repository.
	 * 
	 * @parameter expression="${localRepository}"
	 * @required
	 * @readonly
	 * @since 1.0
	 */
	protected ArtifactRepository localRepository;

	/**
	 * Remote repositories used for the project.
	 * 
	 * @parameter expression="${project.remoteArtifactRepositories}"
	 * @required
	 * @readonly
	 * @since 1.0
	 */
	protected List remoteRepositories;

	/**
	 * The Maven Project Object.
	 * 
	 * @parameter default-value="${project}"
	 * @required
	 * @readonly
	 * @since 1.0
	 */
	protected MavenProject project;

	/**
	 * A {@code DependenciesTool} as borrowed from the license-maven-plugin.
	 * 
	 * @component
	 * @readonly
	 * @since 1.0
	 */
	protected DependenciesTool dependenciesTool;

	/**
	 * A filter to exclude some scopes.
	 * 
	 * @parameter expression="${licensing.excludedScopes}"
	 *            default-value="system"
	 * @since 1.0
	 */
	protected String excludedScopes;

	/**
	 * A filter to include only some scopes, if let empty then all scopes will
	 * be used (no filter).
	 * 
	 * @parameter expression="${licensing.includedScopes}" default-value=""
	 * @since 1.0
	 */
	protected String includedScopes;

	/**
	 * A filter to exclude some GroupIds
	 * 
	 * @parameter expression="${licensing.excludedGroups}" default-value=""
	 * @since 1.0
	 */
	protected String excludedGroups;

	/**
	 * The name of the the XML file which contains licensing information one
	 * artifact.
	 * 
	 * @parameter expression="${thirdPartyLicensingFilename}"
	 *            default-value="third-party-licensing.xml"
	 */
	protected String thirdPartyLicensingFilename;

	/**
	 * The name of the the XML file which contains the aggregated licensing
	 * information for artifacts.
	 * 
	 * @parameter expression="${aggregatedThirdPartyLicensingFilename}"
	 *            default-value="aggregated-third-party-licensing.xml"
	 */
	protected String aggregatedThirdPartyLicensingFilename;

	/**
	 * A filter to include only some GroupIds
	 * 
	 * @parameter expression="${licensing.includedGroups}" default-value=""
	 * @since 1.0
	 */
	protected String includedGroups;

	/**
	 * A filter to exclude some ArtifactsIds
	 * 
	 * @parameter expression="${licensing.excludedArtifacts}" default-value=""
	 * @since 1.0
	 */
	protected String excludedArtifacts;

	/**
	 * A filter to include only some ArtifactsIds
	 * 
	 * @parameter expression="${licensing.includedArtifacts}" default-value=""
	 * @since 1.0
	 */
	protected String includedArtifacts;

	/**
	 * Include transitive dependencies when downloading license files.
	 * 
	 * @parameter default-value="true"
	 * @since 1.0
	 */
	protected boolean includeTransitiveDependencies;

	/**
	 * Should we skip doing licensing checks?
	 * 
	 * @parameter expression="${licensing.skip}" default-value="false"
	 */
	protected boolean skip;

	/**
	 * Location of license requirement XML files.
	 * 
	 * @parameter
	 * @since 1.0
	 */
	protected List licensingRequirementFiles;

	protected LicensingRequirements licensingRequirements = new LicensingRequirements();

	/**
	 * Build a list of artifacts that this project depends on, but resolves them
	 * into {@code MavenProject}s so we can look at their {@code License}
	 * information. Honours all the include/exclude parameters above.
	 * 
	 * @return Does not return null, will return an empty set.
	 */
	protected Collection getProjectDependencies(MavenProject aProject) {

		getLog().debug("Getting dependencies for project: " + aProject.getId());
		Map dependencies = dependenciesTool.loadProjectDependencies(aProject, this, localRepository, remoteRepositories, null);
		getLog().debug("Dependencies found for project: " + dependencies.values().size());
		return dependencies.values();

	}

	/**
	 * Swallow an XML file with licensing requirements. See the
	 * {@code LicensingRequirements} model for more details.
	 * 
	 * @throws MojoExecutionException
	 *             wrapping original exceptions
	 */
	protected void readLicensingRequirements() throws MojoExecutionException {

		XStream xstream = new XStream(new StaxDriver());

		xstream.processAnnotations(LicensingRequirements.class);
		xstream.processAnnotations(ArtifactWithLicenses.class);
		xstream.processAnnotations(CoalescedLicense.class);

		if (licensingRequirementFiles == null) {
			getLog().debug("No licensing requirement files specified.");
			return;
		}

		List requirements = new ArrayList();

		for (String requirementsFile : licensingRequirementFiles) {

			try {
                requirements.add( (LicensingRequirements) xstream.fromXML( locator.getResourceAsInputStream( requirementsFile ) ) );

			} catch (Exception e) {
				throw new MojoExecutionException("Could not read licensing requirements file: " + requirementsFile, e);
			}
		}

		this.licensingRequirements = mergeLicenseRequirements(requirements);
	}

	/**
	 * Combine the separate {@code LicensingRequirements} models into one.
	 * WARNING The {@code CoalescedLicense} merging does not do anything
	 * special.
	 */
	private LicensingRequirements mergeLicenseRequirements(List requirements) {

		LicensingRequirements merged = new LicensingRequirements();

		for (LicensingRequirements req : requirements) {
			merged.combineWith(req);
		}

		return merged;

	}

	/**
	 * As long as the {@code MavenProject} is under at least one liked license,
	 * then it is liked. This method will also consider licensing specified in
	 * licensing requirements; but only if the {@code MavenProject} does not
	 * have its own {@code License} block. If no licensing at all is found then
	 * it is considered disliked.
	 */
	protected boolean isDisliked(MavenProject mavenProject) {

        if ( !isDislikable( mavenProject.getId() ) )
        {
            return false;
        }

        Set licenses = collectLicensesForMavenProject( mavenProject );

        return checkDisliked( licenses );
    }

    /**
     * Check if an artifact is dislikable.
     */
    private boolean isDislikable( String id )
    {
        boolean dislikable = true;
		if (!licensingRequirements.containsDislikedLicenses()
				&& !licensingRequirements.containsLikedLicenses()) {
            dislikable = false;
		}

        if (licensingRequirements.isExemptFromDislike(id)) {
            dislikable = false;
		}
        return dislikable;
    }

    /**
     * Check if there's a disliked license.
     */
    private boolean checkDisliked( Set licenses )
    {
        if (licensingRequirements.containsLikedLicenses()) {
			for (String license : licenses) {

				if (licensingRequirements.isLikedLicense(license))
					return false;
			}
			return true;
		}
		for (String license : licenses) {

			if (!licensingRequirements.isDislikedLicense(license))
				return false;
		}

		return true;
    }

    /**
     * As long as the {@code MavenProject} is under at least one liked license,
     * then it is liked. This method will also consider licensing specified in
     * licensing requirements; but only if the {@code MavenProject} does not
     * have its own {@code License} block. If no licensing at all is found then
     * it is considered disliked.
     */
    protected boolean isDisliked(ArtifactWithLicenses artifactWithLicenses) {

        if ( !isDislikable( artifactWithLicenses.getArtifactId() ) )
        {
            return false;
        }

        Set licenses = artifactWithLicenses.getLicenses();

        return checkDisliked( licenses );
    }

	protected boolean hasLicense(MavenProject mavenProject) {
		return !collectLicensesForMavenProject(mavenProject).isEmpty();
	}

	protected Set collectLicensesForMavenProject(MavenProject mavenProject) {
		Set licenses = new HashSet();

		/**
		 * If an artifact declares a license, we will use it instead of
		 * anything defined in licensing requirements.
		 */
		if (mavenProject.getLicenses() != null && mavenProject.getLicenses().size() > 0) {
			getLog().debug("Licensing: " + mavenProject.getId() + " has licensing information in it.");

			List embeddedLicenses = mavenProject.getLicenses();
			for (License license : embeddedLicenses) {
				if (license.getName() != null) {
					licenses.add(licensingRequirements.getCorrectLicenseName(license.getName()));
				}
			}

		} else {
			Set hardcodedLicenses = licensingRequirements.getLicenseNames(mavenProject.getId());
			for (String license : hardcodedLicenses) {
				licenses.add(licensingRequirements.getCorrectLicenseName(license));
			}
		}

		return licenses;

	}

	@Override
	public boolean isIncludeTransitiveDependencies() {
		return includeTransitiveDependencies;
	}

	@Override
	public List getIncludedScopes() {
		String[] split = includedScopes == null ? new String[0] : includedScopes.split(",");
		return Arrays.asList(split);
	}

	@Override
	public List getExcludedScopes() {
		String[] split = excludedScopes == null ? new String[0] : excludedScopes.split(",");
		return Arrays.asList(split);
	}

	@Override
	public String getIncludedArtifacts() {
		return includedArtifacts;
	}

	@Override
	public String getIncludedGroups() {
		return includedGroups;
	}

	@Override
	public String getExcludedGroups() {
		return excludedGroups;
	}

	@Override
	public String getExcludedArtifacts() {
		return excludedArtifacts;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy