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

com.metaeffekt.artifact.analysis.workbench.WorkbenchUtils Maven / Gradle / Ivy

There is a newer version: 0.126.0
Show newest version
/*
 * 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