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

com.metaeffekt.conversion.plugin.ConvertInventoryToSpdxMojo 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.conversion.plugin;

import com.metaeffekt.artifact.analysis.bom.BomConstants;
import com.metaeffekt.artifact.analysis.bom.spdx.DocumentSpec;
import com.metaeffekt.artifact.analysis.bom.spdx.SpdxExporter;
import org.apache.commons.io.FilenameUtils;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.metaeffekt.core.inventory.processor.reader.InventoryReader;

import java.io.File;
import java.io.IOException;
import java.security.Security;
import java.util.UUID;

/**
 * Mojo for exporting an artifact inventory to an SPDX format.
 */
@Mojo(name = "convert-inventory-to-spdx", defaultPhase = LifecyclePhase.PROCESS_RESOURCES)
public class ConvertInventoryToSpdxMojo extends AbstractInventoryConversionMojo {

    @Parameter(required = true)
    private String documentName;

    @Parameter(defaultValue = "An automatically generated document adhering to the SPDX specification.")
    private String description;

    @Parameter(required = true, defaultValue = "https://metaeffekt.com/cyclonedx/doc/")
    private String documentIdPrefix;

    @Parameter(required = true)
    private String organization;

    @Parameter(required = true)
    private String organizationUrl;

    @Parameter
    private String person;

    @Parameter
    private String comment;

    @Parameter
    private String spdxLicenseListVersion;

    @Parameter( defaultValue = "JSON")
    private BomConstants.Format outputFormat;

    // The current iteration of this bom
    @Parameter(defaultValue = "1")
    private int documentIteration;

    // Switch to decide if relationship structures should be included or "pressed flat" / omitted.
    @Parameter(defaultValue = "true")
    private boolean mapRelationships;

    // Switch to decide if license expressions or full single licenses should be used.
    @Parameter(defaultValue = "true")
    private boolean useLicenseExpressions;

    // Switch to decide if license texts should be omitted or not.
    @Parameter(defaultValue = "true")
    private boolean includeLicenseTexts;

    // Switch to decide if assets should be removed as a pre-step before exporting.
    @Parameter(defaultValue = "true")
    private boolean includeAssets;

    // Switch to decide if additional properties needed for lossless importing, not in inventory, should be added.
    @Parameter(defaultValue = "false")
    private boolean includeTechnicalProperties;

    /**
     * Any additional attribute keys from the input inventory which should be captured by the exporter. If this is not
     * set the exporter will only map the predefined attributes.
     */
    @Parameter
    private File approvedAttributes;

    /**
     * Any custom license mappings which should be captured by the exporter, this replaces the LicenseRef-unknown entries
     * with the mapping provided.
     */
    @Parameter
    private File customLicenseMappings;

    @Parameter(defaultValue = "true")
    boolean prettyPrint;

    @Override
    protected void runWithFiles() throws MojoExecutionException, MojoFailureException {
        if (input.getName().endsWith("xls") || input.getName().endsWith("xlsx")) {
            run(input, output);
        } else {
            throw new MojoExecutionException("Unsupported input format: " + input.getName());
        }
    }

    @Override
    protected void runWithDirectories() throws MojoExecutionException, MojoFailureException {
        File[] inputFiles = input.listFiles();

        if (inputFiles != null) {
            for (File file : inputFiles) {
                if (file.getName().endsWith("xls") || file.getName().endsWith("xlsx")) {
                    if (outputFormat.equals(BomConstants.Format.JSON)) {
                        run(file, new File(output, FilenameUtils.removeExtension(file.getName()) + ".json"));
                    } else if (outputFormat.equals(BomConstants.Format.XML)) {
                        run(file, new File(output, FilenameUtils.removeExtension(file.getName()) + ".xml"));
                    } else {
                        throw new MojoExecutionException("Unsupported output format: " + outputFormat);
                    }
                }
            }
        }
    }

    // FIXME-JFU: see parameterization FIXME in CycloneDxMojo
    // FIXME-JFU: check whether we can also determine the document license on plugin configuration level
    private void run(File inputFile, File outputFile) throws MojoExecutionException, MojoFailureException {
        DocumentSpec documentSpec = new DocumentSpec(documentName, documentIdPrefix + UUID.randomUUID(), organization, organizationUrl)
                .withDescription(description)
                .byPerson(person)
                .usingTool("{metaeffekt} Kontinuum CycloneDx Exporter")
                .withComment(comment)
                .withSpdxLicenseListVersion(spdxLicenseListVersion)
                .usingFormat(outputFormat)
                .setDocumentIteration(documentIteration)
                .mapRelationships(mapRelationships)
                .useLicenseExpressions(useLicenseExpressions)
                .includeLicenseTexts(includeLicenseTexts)
                .includeAssets(includeAssets)
                .includeTechnicalProperties(includeTechnicalProperties);

        if (Security.getProvider("BC") == null) {
            Security.addProvider(new BouncyCastleProvider());
        }

        SpdxExporter spdxExporter = new SpdxExporter(approvedAttributes, getNormalizationMetaData(), getLicenseTextProvider(), customLicenseMappings);
        try {
            spdxExporter.exportToSpdxDocument(new InventoryReader().readInventory(inputFile),
                    outputFile, documentSpec, prettyPrint);
        } catch (IOException e) {
            throw new MojoExecutionException("Failed to read inventory: " + inputFile.getPath());
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy