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

org.codehaus.mojo.license.download.LicenseMatchers Maven / Gradle / Ivy

The newest version!
package org.codehaus.mojo.license.download;

/*
 * #%L
 * License Maven Plugin
 * %%
 * Copyright (C) 2018 Codehaus
 * %%
 * 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
 * .
 * #L%
 */

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;

import org.apache.maven.plugin.MojoExecutionException;

/**
 * A collection of {@link DependencyMatcher}s to match and replace licenses in {@link ProjectLicenseInfo} instances.
 *
 * @author Peter Palaga
 * @since 1.18
 */
public class LicenseMatchers {

    private static final Pattern MATCH_EMPTY_PATTERN = Pattern.compile("");
    private static final Pattern MATCH_ALL_PATTERN = Pattern.compile(".*");

    /**
     * @return a new {@link Builder}
     */
    public static Builder builder() {
        return new Builder();
    }

    /**
     * @param licenseMatchersFile
     * @return new {@link LicenseMatchers} configured from the given {@code licenseMatchersFile}
     * @throws MojoExecutionException
     */
    public static LicenseMatchers load(File licenseMatchersFile) throws MojoExecutionException {
        final List matchers = new ArrayList<>();
        try {
            if (licenseMatchersFile != null && licenseMatchersFile.exists()) {
                final List replacements =
                        LicenseSummaryReader.parseLicenseSummary(licenseMatchersFile);

                for (ProjectLicenseInfo dependency : replacements) {
                    matchers.add(DependencyMatcher.of(dependency));
                }
            }
        } catch (Exception e) {
            throw new MojoExecutionException("Could not parse licensesReplacementsFile " + licenseMatchersFile, e);
        }
        return new LicenseMatchers(matchers);
    }

    private static boolean match(Pattern pattern, String string) {
        return string == null
                ? pattern.matcher("").matches()
                : pattern.matcher(string).matches();
    }

    private static Pattern pattern(String string, boolean isPre118Match) {
        return string == null || string.isEmpty()
                ? MATCH_EMPTY_PATTERN
                : isPre118Match
                        ? Pattern.compile(Pattern.quote(string))
                        : Pattern.compile(string, Pattern.CASE_INSENSITIVE);
    }

    private final List matchers;

    private LicenseMatchers(List matchers) {
        super();
        this.matchers = matchers;
    }

    /**
     * Replace matching licenses in the given {@code dependency}
     *
     * @param dependency
     */
    public void replaceMatches(ProjectLicenseInfo dependency) {
        for (DependencyMatcher matcher : matchers) {
            if (matcher.matches(dependency)) {
                if (matcher.isApproved()) {
                    /* do nothing */
                } else {
                    dependency.setLicenses(matcher.cloneLicenses());
                }
                dependency.setApproved(true);
                dependency.getDownloaderMessages().clear();
            }
        }
    }

    /**
     * A {@link LicenseMatchers} builder
     */
    public static class Builder {
        private List matchers = new ArrayList<>();

        public Builder matcher(DependencyMatcher matcher) {
            matchers.add(matcher);
            return this;
        }

        public LicenseMatchers build() {
            final List ms = matchers;
            matchers = null;
            return new LicenseMatchers(ms);
        }
    }

    /**
     * A matcher for dependency nodes in a licenses.xml file
     *
     * @since 1.18
     */
    static class DependencyMatcher {

        public static DependencyMatcher of(ProjectLicenseInfo dependency) {
            final String version = dependency.getVersion();
            final boolean isPre118Match = !dependency.hasMatchLicenses();
            return new DependencyMatcher(
                    pattern(dependency.getGroupId(), isPre118Match),
                    pattern(dependency.getArtifactId(), isPre118Match),
                    isPre118Match || version == null || version.isEmpty()
                            ? MATCH_ALL_PATTERN
                            : Pattern.compile(version, Pattern.CASE_INSENSITIVE),
                    LicenseListMatcher.of(dependency),
                    dependency.cloneLicenses(),
                    dependency.isApproved());
        }

        private final Pattern artifactId;

        private final Pattern groupId;

        private final LicenseListMatcher licenseListMatcher;

        private final boolean approved;
        private final List licenses;

        private final Pattern version;

        DependencyMatcher(
                Pattern groupId,
                Pattern artifactId,
                Pattern version,
                LicenseListMatcher licenseListMatcher,
                List licenses,
                boolean approved) {
            super();
            this.groupId = groupId;
            this.artifactId = artifactId;
            this.version = version;
            this.licenseListMatcher = licenseListMatcher;
            this.licenses = licenses;
            this.approved = approved;
        }

        public List getLicenseMatchers() {
            return null;
        }

        /**
         * @return a deep clone of {@link #licenses}
         */
        public List cloneLicenses() {
            try {
                final ArrayList result = new ArrayList<>(licenses != null ? licenses.size() : 0);
                if (licenses != null) {
                    for (ProjectLicense license : licenses) {
                        result.add(license.clone());
                    }
                }
                return result;
            } catch (CloneNotSupportedException e) {
                throw new RuntimeException(e);
            }
        }

        public boolean matches(ProjectLicenseInfo dependency) {
            return match(groupId, dependency.getGroupId())
                    && match(artifactId, dependency.getArtifactId())
                    && match(version, dependency.getVersion())
                    && licenseListMatcher.matches(dependency.getLicenses());
        }

        public boolean isApproved() {
            return approved;
        }
    }

    /**
     * A matcher for lists of {@link ProjectLicense}s.
     *
     * @since 1.18
     */
    static class LicenseListMatcher {
        private final List licenseMatchers;

        private static final LicenseListMatcher MATCHES_ALL_LICENSE_LIST_MATCHER = new LicenseListMatcher(null) {
            @Override
            public boolean matches(List licenses) {
                return true;
            }
        };

        LicenseListMatcher(List licenseMatchers) {
            this.licenseMatchers = licenseMatchers;
        }

        public boolean matches(List licenses) {
            final int licsSize = licenses == null ? 0 : licenses.size();
            if (licenseMatchers.size() != licsSize) {
                return false;
            }
            final Iterator matchersIt = licenseMatchers.iterator();
            final Iterator licsIt = licenses.iterator();
            while (matchersIt.hasNext()) {
                if (!matchersIt.next().matches(licsIt.next())) {
                    return false;
                }
            }
            return true;
        }

        public static LicenseListMatcher of(ProjectLicenseInfo dependency) {
            if (!dependency.hasMatchLicenses()) {
                return MATCHES_ALL_LICENSE_LIST_MATCHER;
            }

            final List licenseMatchers;
            final List rawMatchers = dependency.getMatchLicenses();
            if (rawMatchers == null || rawMatchers.isEmpty()) {
                licenseMatchers = Collections.emptyList();
            } else {
                licenseMatchers = new ArrayList<>();
                for (ProjectLicense lic : rawMatchers) {
                    licenseMatchers.add(
                            new LicenseMatcher(lic.getName(), lic.getUrl(), lic.getDistribution(), lic.getComments()));
                }
            }
            return new LicenseListMatcher(licenseMatchers);
        }
    }

    /**
     * A matcher for single {@link ProjectLicense}s.
     *
     * @since 1.18
     */
    static class LicenseMatcher {

        private final Pattern comments;
        private final Pattern distribution;
        private final Pattern name;
        private final Pattern url;

        LicenseMatcher(Pattern name, Pattern url, Pattern distribution, Pattern comments) {
            super();
            this.name = name;
            this.url = url;
            this.distribution = distribution;
            this.comments = comments;
        }

        LicenseMatcher(String name, String url, String distribution, String comments) {
            super();
            this.name = pattern(name, false);
            this.url = pattern(url, false);
            this.distribution = pattern(distribution, false);
            this.comments = pattern(comments, false);
        }

        public boolean matches(ProjectLicense license) {
            return match(name, license.getName())
                    && match(url, license.getUrl())
                    && match(distribution, license.getDistribution())
                    && match(comments, license.getComments());
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy