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

com.metaeffekt.artifact.extractors.configuration.PackageExtractorConfiguration Maven / Gradle / Ivy

The 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.extractors.configuration;

import com.metaeffekt.artifact.analysis.utils.FileUtils;
import com.metaeffekt.artifact.analysis.utils.StringUtils;
import org.metaeffekt.core.inventory.processor.model.Artifact;
import org.metaeffekt.core.inventory.processor.model.Constants;
import org.metaeffekt.core.inventory.processor.model.Inventory;
import org.metaeffekt.core.inventory.processor.reader.InventoryReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;

import static com.metaeffekt.artifact.analysis.metascan.Constants.KEY_CONTENT_CHECKSUM;

public class PackageExtractorConfiguration extends AbstractExtractorConfiguration {

    private static final Logger LOG = LoggerFactory.getLogger(PackageExtractorConfiguration.class);

    /**
     * In this file location the packages can be found; the package names are usually version agnostic.
     */
    private final File packageDocBaseDir;

    /**
     * In this file location the package licenses can be found; the package names are usually version agnostic.
     */
    private final File packageLicenseBaseDir;

    protected PackageExtractorConfiguration(String id, File inventoryFile) {
        super(id, inventoryFile);

        this.packageDocBaseDir = null;
        this.packageLicenseBaseDir = null;
    }

    public PackageExtractorConfiguration(String id, File inventoryFile, File analysisDir) {
        super(id, inventoryFile);
        this.packageDocBaseDir = exist(new File(analysisDir, "usr-share-doc"));
        this.packageLicenseBaseDir = exist(new File(analysisDir, "usr-share-licenses"));
    }

    public void validate() {
        FileUtils.validateExists(getResultInventoryFile());
    }

    public void contribute(File targetDir, Inventory aggregatedInventory) throws IOException {
        final Inventory inventory = new InventoryReader().readInventory(getResultInventoryFile());

        int i = 0;
        int size = inventory.getArtifacts().size();

        final File tmpFolder = new File(targetDir.getParentFile(), ".tmp");
        if (tmpFolder.exists()) {
            FileUtils.deleteDirectoryQuietly(tmpFolder);
        }

        FileUtils.forceMkDirQuietly(tmpFolder);

        for (Artifact artifact : inventory.getArtifacts()) {
            artifact.deriveArtifactId();
            i++;

            final String artifactType = artifact.get(Constants.KEY_TYPE);

            if (Constants.ARTIFACT_TYPE_PACKAGE.equals(artifactType)) {
                LOG.info("Compressing [{}], {}/{}", artifact.getId(), i, size);

                final File tmpAggregationFolder = new File(tmpFolder, "content_" + artifact.getId());

                if (packageDocBaseDir != null && packageDocBaseDir.exists()) {
                    // VALIDATE COMMENT: the source dir default is the artifactId (id without version)
                    final File generalDir = new File(packageDocBaseDir, artifact.getArtifactId());
                    final String specificDir = artifact.get(Constants.KEY_DOCUMENTATION_PATH_PACKAGE);
                    contributeDirectory(artifact, generalDir, specificDir, "[doc]", tmpAggregationFolder);
                }

                if (packageLicenseBaseDir != null && packageLicenseBaseDir.exists()) {
                    final File generalDir = new File(packageLicenseBaseDir, artifact.getArtifactId());
                    final String specificDir = artifact.get(Constants.KEY_LICENSE_PATH_PACKAGE);
                    contributeDirectory(artifact, generalDir, specificDir, "[license]", tmpAggregationFolder);
                }

                createArchiveFromAggregationFolder(artifact, tmpAggregationFolder, targetDir, tmpFolder);
            }

        }

        addToInventory(inventory, aggregatedInventory);
    }

    static void createArchiveFromAggregationFolder(Artifact artifact, File tmpAggregationFolder, File targetDir, File tmpFolder) throws IOException {
        // NOTE: for some reason it is not enough to check the file does not exist.
        if (tmpAggregationFolder.exists() && tmpAggregationFolder.isDirectory()) {

            // FIXME: simplify; in this case we do not know the filename yet; artifactId is not a sufficient
            // discriminator. Other artifacts may have the same id (not in the analysis step however)
            final File contentChecksumFile = new File(tmpFolder, artifact.getArtifactId() + ".content.md5");
            FileUtils.createDirectoryContentChecksumFile(tmpAggregationFolder, contentChecksumFile);
            final String contentChecksum = FileUtils.computeChecksum(contentChecksumFile);

            // set the content checksum
            artifact.set(KEY_CONTENT_CHECKSUM, contentChecksum);

            File targetZipFile = new File(targetDir, String.format("%s-%s.zip", artifact.getArtifactId(), contentChecksum));
            FileUtils.zipAnt(tmpAggregationFolder, targetZipFile);

            // check file exists; move or delete tmp file
            artifact.set("Archive Path", targetZipFile.getAbsolutePath());

            // unset the analysis path; this may be propagated from a reference artifact and may point to
            // the wrong folder. The workbench will recreate this information when the archive file is unpacked.
            artifact.set("Analysis Path", null);
        }
    }

    private void contributeDirectory(Artifact artifact, File generalDir, String specificDir, String context, File tmpAggregationFolder) {
        // if the artifact has better information, we use that path instead
        if (StringUtils.notEmpty(specificDir)) {
            // FIXME: we need to modulate the path if extracted in a different environment

            final File sourceDirCandidate = new File(specificDir);
            if (sourceDirCandidate.exists() && sourceDirCandidate.isDirectory()) {
                generalDir = sourceDirCandidate;
            }
        }

        if (generalDir.exists()) {
            File targetChildFolder = new File(tmpAggregationFolder, context);
            FileUtils.forceMkDirQuietly(targetChildFolder);
            try {
                FileUtils.copyDirectory(generalDir, targetChildFolder);
            } catch (Exception e) {
                LOG.error("Cannot contribute directory {}. {}", generalDir, e.getMessage());
                artifact.append("Errors", "Directory " + generalDir + " was not copied.", "\n");
            }
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy