com.metaeffekt.artifact.analysis.workbench.WorkbenchUtils Maven / Gradle / Ivy
/*
* Copyright 2021-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.metaeffekt.artifact.analysis.workbench;
import com.metaeffekt.artifact.analysis.utils.InventoryUtils;
import com.metaeffekt.artifact.analysis.utils.StringUtils;
import com.metaeffekt.artifact.terms.model.TermsMetaData;
import org.metaeffekt.core.inventory.processor.model.Artifact;
import org.metaeffekt.core.inventory.processor.model.Inventory;
import org.metaeffekt.core.inventory.processor.model.LicenseData;
import java.util.*;
import static com.metaeffekt.artifact.analysis.metascan.Constants.*;
public class WorkbenchUtils extends InventoryUtils {
private static Set collectArtifactLicenses(Inventory projectInventory, Artifact artifact, boolean includeDerivedLicenses) {
final HashSet artifactLicenseSet = new HashSet<>();
final List associatedLicenses = InventoryUtils.tokenizeLicense(artifact.getLicense(), false, false);
final List effectiveLicenses = projectInventory.getEffectiveLicenses(artifact);
artifactLicenseSet.addAll(associatedLicenses);
artifactLicenseSet.addAll(effectiveLicenses);
// only include derived in case associated / effective licenses are not managed
// NOTE: alternatively associated and effective licenses could be marked in the summary
if (associatedLicenses.isEmpty() && effectiveLicenses.isEmpty() && includeDerivedLicenses) {
artifactLicenseSet.addAll(InventoryUtils.tokenizeLicense(
artifact.get(KEY_DERIVED_LICENSES), false, true));
artifactLicenseSet.addAll(InventoryUtils.tokenizeLicense(
artifact.get(KEY_BINARY_ARTIFACT_DERIVED_LICENSES), false, true));
artifactLicenseSet.addAll(InventoryUtils.tokenizeLicense(
artifact.get(KEY_SOURCE_ARTIFACT_DERIVED_LICENSES), false, true));
artifactLicenseSet.addAll(InventoryUtils.tokenizeLicense(
artifact.get(KEY_SOURCE_ARCHIVE_DERIVED_LICENSES), false, true));
artifactLicenseSet.addAll(InventoryUtils.tokenizeLicense(
artifact.get(KEY_DESCRIPTOR_DERIVED_LICENSES), false, true));
artifactLicenseSet.addAll(InventoryUtils.tokenizeLicense(
artifact.get(PackageLicenseTransformer.PACKAGE_SPECIFIED_LICENSE_MAPPED), false, true));
artifactLicenseSet.addAll(InventoryUtils.tokenizeLicense(
artifact.get(PackageLicenseTransformer.COMPONENT_SPECIFIED_LICENSE_MAPPED), false, true));
}
// expand options
final Set licenseOptions = new HashSet<>();
for (String license : artifactLicenseSet) {
if (license.contains(" + ")) {
licenseOptions.addAll(tokenizeLicense(license, false, false));
}
}
artifactLicenseSet.addAll(licenseOptions);
return artifactLicenseSet;
}
public static void addLicenseData(Inventory projectInventory) {
addLicenseData(projectInventory, false, false);
}
public static void addLicenseData(Inventory projectInventory, boolean failOnMissingLicenseData) {
addLicenseData(projectInventory, failOnMissingLicenseData, false);
}
public static void addLicenseData(Inventory projectInventory, boolean failOnMissingLicenseData, boolean includeDerivedLicenses) {
if (NORMALIZATION_META_DATA == null) {
throw new IllegalStateException("Method addLicenseData requires TermsMetaData to be initialized.");
}
final Set canonicalNames = new HashSet<>();
final Map> artifactLicenseSetMap = new HashMap<>();
// collect canonical names from associated and effective licenses; if required include derived licenses (binary, source, pom)
for (final Artifact artifact : projectInventory.getArtifacts()) {
final Set artifactLicenseSet = collectArtifactLicenses(projectInventory, artifact, includeDerivedLicenses);
artifactLicenseSetMap.put(artifact, artifactLicenseSet);
canonicalNames.addAll(artifactLicenseSet);
}
// ANY is just a placeholder the scanner uses
canonicalNames.remove("ANY");
canonicalNames.remove("(");
canonicalNames.remove(")");
// collect missed canonical names in a dedicated set
final Set licenseWithoutTermsMetadata = new HashSet<>();
// check TMD availability; resolve representedAs and include licenses
for (final String canonicalName : new HashSet<>(canonicalNames)) {
final TermsMetaData termsMetaData = NORMALIZATION_META_DATA.getTermsMetaData(canonicalName);
if (termsMetaData == null) {
licenseWithoutTermsMetadata.add(canonicalName);
} else {
final String representedAs = termsMetaData.getRepresentedAs();
if (representedAs != null) {
final TermsMetaData representedAsTermsMetaData = NORMALIZATION_META_DATA.getTermsMetaData(representedAs);
if (representedAsTermsMetaData != null) {
// include representedAs license
canonicalNames.add(representedAsTermsMetaData.getCanonicalName());
} else {
// otherwise report missing
licenseWithoutTermsMetadata.add(representedAs);
}
}
}
}
if (!licenseWithoutTermsMetadata.isEmpty()) {
if (failOnMissingLicenseData) {
throw new IllegalStateException("No terms metadata resolved for canonical names " + licenseWithoutTermsMetadata + ".");
}
// NOTE: we do not log information here. Validation is performed elsewhere
}
// insert information; manage duplicates
insertLicenseDataForCanonicalNames(canonicalNames, projectInventory);
// collect asset ids
final Set assetIds = collectAssetIdsFromAssetMetaData(projectInventory);
assetIds.addAll(collectAssetIdsFromArtifacts(projectInventory));
// insert cross tables
for (LicenseData licenseData : projectInventory.getLicenseData()) {
final String canonicalName = licenseData.get(LicenseData.Attribute.CANONICAL_NAME);
boolean isPackage = false;
boolean isWebModule = false;
for (Artifact artifact : projectInventory.getArtifacts()) {
final String type = artifact.get("Type");
final Set licenses = artifactLicenseSetMap.get(artifact);
if (licenses.contains(canonicalName)) {
if (type != null) {
if (!licenses.isEmpty()) {
if (licenses.contains(canonicalName)) {
isPackage |= type.contains(org.metaeffekt.core.inventory.processor.model.Constants.ARTIFACT_TYPE_PACKAGE);
// backwards compatibility
isPackage |= type.contains("package");
isWebModule |= type.contains(org.metaeffekt.core.inventory.processor.model.Constants.ARTIFACT_TYPE_NODEJS_MODULE);
// backwards compatibility
isWebModule |= type.contains("nodejs-module");
}
}
}
// iterate asset ids to also cover containment / is relationship
final String artifactAssetId = InventoryUtils.deriveAssetIdFromArtifact(artifact);
for (String assetId : assetIds) {
final String artifactInAsset = artifact.get(assetId);
if (StringUtils.hasText(artifactInAsset)) {
licenseData.set(assetId, artifactInAsset);
}
if (artifactAssetId != null && artifactAssetId.equals(assetId)) {
licenseData.set(artifactAssetId, org.metaeffekt.core.inventory.processor.model.Constants.MARKER_CROSS);
}
}
}
}
// NOTE: represented as licenses not directly used will not receive marks
licenseData.set("Type Package", isPackage ? "x" : "");
licenseData.set("Type Web Module", isWebModule ? "x" : "");
licenseData.set("Type Artifact", isPackage || isWebModule ? "" : "x");
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy