org.codehaus.mojo.license.download.PreferredFileNames Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of license-maven-plugin Show documentation
Show all versions of license-maven-plugin Show documentation
Maven plugin to download and collect license files from project dependencies.
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.AbstractMap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.regex.Pattern;
import org.codehaus.mojo.license.spdx.SpdxLicenseInfo;
import org.codehaus.mojo.license.spdx.SpdxLicenseInfo.Attachments.UrlInfo;
import org.codehaus.mojo.license.spdx.SpdxLicenseList;
import org.codehaus.mojo.license.utils.FileUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* An url -> {@link FileNameEntry} mapping.
*
* @author Peter Palaga
* @since 1.18
*/
// CHECKSTYLE_OFF: MethodLength
public class PreferredFileNames {
private static final Logger LOG = LoggerFactory.getLogger(PreferredFileNames.class);
/**
* @param licensesOutputDirectory
* @param licenseUrlFileNames
* @return a new {@link PreferredFileNames} built of AbstractDownloadLicensesMojo.licenseUrlFileNames
*/
public static PreferredFileNames build(File licensesOutputDirectory, Map licenseUrlFileNames) {
final Map>> fileNameToUrlPatterns = new LinkedHashMap<>();
final Map sha1TofileName = new LinkedHashMap();
if (licenseUrlFileNames != null) {
if (licenseUrlFileNames.containsKey("spdx")) {
spdx(fileNameToUrlPatterns, sha1TofileName);
}
for (Entry en : licenseUrlFileNames.entrySet()) {
final String fileName = en.getKey();
if (fileName != null && !fileName.isEmpty()) {
if ("spdx".equals(fileName)) {
// ignore
} else if (en.getValue() != null) {
String[] rawPatters = en.getValue().split("\\s+");
if (rawPatters != null) {
final List patterns = new ArrayList<>();
String sha1 = null;
for (String rawPattern : rawPatters) {
if (rawPattern.startsWith("sha1:")) {
if (sha1 != null) {
throw new IllegalStateException(
"sha1 defined twice for licenseFileName '" + fileName + "'");
}
sha1 = rawPattern.substring(5);
} else {
patterns.add(Pattern.compile(rawPattern, Pattern.CASE_INSENSITIVE));
}
}
if (sha1 != null) {
sha1TofileName.put(sha1, fileName);
}
fileNameToUrlPatterns.put(
fileName,
new AbstractMap.SimpleImmutableEntry<>(
sha1, Collections.unmodifiableList(patterns)));
}
}
}
}
}
return new PreferredFileNames(licensesOutputDirectory, fileNameToUrlPatterns, sha1TofileName);
}
private static void spdx(
Map>> result, Map sha1TofileName) {
final Map>> fileNameToUrlPatterns = new TreeMap<>();
final SpdxLicenseList spdxList = SpdxLicenseList.getLatest();
final Map lics = spdxList.getLicenses();
LOG.info("Honoring {} SPDX licenses", lics.size());
/* Count in how many licenses is the given sha1 used */
final Map> sha1ToLicenseIds = new HashMap<>();
final Map> sha1ToUrls = new HashMap<>();
final Set stableSha1s = new HashSet<>();
for (SpdxLicenseInfo lic : lics.values()) {
if (!lic.isDeprecatedLicenseId()) {
for (Entry urlInfoEntry :
lic.getAttachments().getUrlInfos().entrySet()) {
final UrlInfo urlInfo = urlInfoEntry.getValue();
if (urlInfo.getSha1() != null && urlInfo.getMimeType() != null) {
final String sha1 = urlInfo.getSha1();
if (urlInfo.isStable()) {
stableSha1s.add(sha1);
}
Set licIds = sha1ToLicenseIds.get(sha1);
if (licIds == null) {
licIds = new TreeSet<>();
sha1ToLicenseIds.put(sha1, licIds);
}
licIds.add(lic.getLicenseId());
Set urls = sha1ToUrls.get(sha1);
if (urls == null) {
urls = new TreeSet<>();
sha1ToUrls.put(sha1, urls);
}
urls.add(urlInfoEntry.getKey());
}
}
}
}
/* For license sets in which a given sha1 is used, check if a . name would be unique */
for (Entry> sha1LicenseId : sha1ToLicenseIds.entrySet()) {
final Set licIds = sha1LicenseId.getValue();
final StringBuilder baseNameBuilder = new StringBuilder();
final Map> mimeTypeToSha1 = new HashMap<>();
for (String licId : licIds) {
if (baseNameBuilder.length() > 0) {
baseNameBuilder.append("-OR-");
}
baseNameBuilder.append(licId);
final SpdxLicenseInfo lic = lics.get(licId);
for (Entry urlInfoEntry :
lic.getAttachments().getUrlInfos().entrySet()) {
final UrlInfo urlInfo = urlInfoEntry.getValue();
final String mimeType = urlInfo.getMimeType();
if (sha1ToLicenseIds.containsKey(urlInfo.getSha1()) && mimeType != null) {
Set sha1s = mimeTypeToSha1.get(mimeType);
if (sha1s == null) {
sha1s = new LinkedHashSet<>();
mimeTypeToSha1.put(mimeType, sha1s);
}
sha1s.add(urlInfo.getSha1());
}
}
}
final String baseName = baseNameBuilder.toString();
for (Entry> mimeTypeSha1 : mimeTypeToSha1.entrySet()) {
final String mimeType = mimeTypeSha1.getKey();
if (mimeType == null) {
throw new IllegalStateException("mimeType must not be null");
}
final Set sha1s = mimeTypeSha1.getValue();
for (String sha1 : sha1s) {
final String uniqueName = sha1s.size() == 1 ? baseName : (baseName + "-" + sha1.substring(0, 7));
final String fileName = uniqueName + FileUtil.toExtension(mimeType, true);
final List patterns = new ArrayList<>();
Set urls = sha1ToUrls.get(sha1);
for (String url : urls) {
patterns.add(Pattern.compile(Pattern.quote(url), Pattern.CASE_INSENSITIVE));
}
final String useSha1 = stableSha1s.contains(sha1) ? sha1 : null;
if (useSha1 != null) {
sha1TofileName.put(useSha1, fileName);
}
final List usePatterns = Collections.unmodifiableList(patterns);
final Entry> avail = fileNameToUrlPatterns.get(fileName);
if (avail == null) {
fileNameToUrlPatterns.put(
fileName, new AbstractMap.SimpleImmutableEntry<>(useSha1, usePatterns));
} else if (!(avail.getKey() == useSha1
|| (avail.getKey() != null && avail.getKey().equals(useSha1)))
|| !isEqual(usePatterns, avail.getValue())) {
LOG.warn("Available: {}, {}, {}", fileName, avail.getKey(), avail.getValue());
LOG.warn("To add : {}, {}, {}", fileName, useSha1, patterns);
throw new IllegalStateException(fileName + " already present");
}
}
}
}
if (LOG.isDebugEnabled()) {
final StringBuilder sb = new StringBuilder();
sb.append("\n");
for (Entry>> en : fileNameToUrlPatterns.entrySet()) {
final String fileName = en.getKey();
final String sha1 = en.getValue().getKey();
final List patterns = en.getValue().getValue();
sb.append(" <" + fileName + ">\n");
if (sha1 != null) {
sb.append(" sha1:" + sha1 + "\n");
}
for (Pattern pattern : patterns) {
sb.append(" " + pattern.pattern() + "\n");
}
sb.append(" " + fileName + ">\n");
}
sb.append(" \n");
LOG.debug("SPDX licenseUrlFileNames:");
LOG.debug(sb.toString());
}
result.putAll(fileNameToUrlPatterns);
}
private static boolean isEqual(final List newPatterns, List oldPatterns) {
if (oldPatterns.size() != newPatterns.size()) {
return false;
}
final Iterator newIt = newPatterns.iterator();
final Iterator oldIt = oldPatterns.iterator();
while (newIt.hasNext()) {
if (!newIt.next().pattern().equals(oldIt.next().pattern())) {
return false;
}
}
return true;
}
private final File licensesOutputDirectory;
private final Map>> fileNameToUrlPatterns;
private final Map sha1ToFileName;
public PreferredFileNames(
File licensesOutputDirectory,
Map>> fileNameToUrlPatterns,
Map sha1ToFileName) {
super();
this.licensesOutputDirectory = licensesOutputDirectory;
this.fileNameToUrlPatterns = fileNameToUrlPatterns;
this.sha1ToFileName = sha1ToFileName;
}
/**
* @param sha1 the checksum to search by
* @return a file name bound the given {@code sha1} checksum or {@code null}
*/
public String getFileNameBySha1(String sha1) {
return sha1ToFileName.get(sha1);
}
/**
* @param url the URL to query
* @return the preferred {@link FileNameEntry} for the given {@code url} or {@code null}
*/
public FileNameEntry getEntryByUrl(String url) {
for (Entry>> fn : fileNameToUrlPatterns.entrySet()) {
for (Pattern pat : fn.getValue().getValue()) {
if (pat.matcher(url).matches()) {
LOG.debug(
"Using file name '{}' for URL '{}' that matched pattern '{}'",
fn.getKey(),
url,
pat.pattern());
return new FileNameEntry(
new File(licensesOutputDirectory, fn.getKey()),
true,
fn.getValue().getKey());
}
}
}
return null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy