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

com.checkmarx.configprovider.RemoteRepoDownloader Maven / Gradle / Ivy

package com.checkmarx.configprovider;

import com.checkmarx.configprovider.dto.RepoDto;
import com.checkmarx.configprovider.dto.SourceProviderType;
import com.checkmarx.configprovider.dto.interfaces.ConfigResource;
import com.checkmarx.configprovider.exceptions.ConfigProviderException;
import com.checkmarx.configprovider.resource.FileContentResource;
import com.checkmarx.configprovider.resource.ParsableResource;

import com.checkmarx.configprovider.interfaces.SourceControlClient;
import lombok.extern.slf4j.Slf4j;
import javax.naming.ConfigurationException;
import java.lang.reflect.InvocationTargetException;
import java.util.*;

import java.util.stream.Collectors;

@Slf4j
public class RemoteRepoDownloader {

    private static final EnumMap> sourceProviderMapping;

    static {
        sourceProviderMapping = new EnumMap<>(SourceProviderType.class);
        sourceProviderMapping.put(SourceProviderType.GITHUB, GitHubClient.class);
    }

    private RepoDto repoDto;


    public ParsableResource loadFileByName(SourceControlClient client, RepoDto repo, String folder, String fileToFind, List filenames )  {
        return Optional.ofNullable(fileToFind)
        .filter(filenames::contains)
        .map(foundFile -> downloadFiles(client, repo, folder, Collections.singletonList(foundFile)).get(0))
        .orElse(null);
    }


    public List loadFileBySuffix(SourceControlClient client, RepoDto repo, String folder, String suffix, List folderFiles ) {

        List matchingFiles = Optional.ofNullable(suffix)
        .map(thesuffix -> folderFiles.stream()
        .filter(name -> name.endsWith(thesuffix))
        .collect(Collectors.toList()))
        .orElse(new LinkedList<>());
        
        return matchingFiles.isEmpty() ? new LinkedList<>() : downloadFiles(client, repo, folder,matchingFiles);
    }
    

    public List downloadRepoFiles(RepoDto repo, List folders, String nameToFind, String suffixToFind) throws ConfigurationException {
        log.info("Searching for a config-as-code file in a remote repo");
        validate(repo);

        this.repoDto = repo;
        List resources = new LinkedList<>();
        
        SourceControlClient client = determineSourceControlClient();

        for (String folder : folders) {
            List filenames = client.getDirectoryFilenames(repo, folder);

            ParsableResource specificFile = loadFileByName(client, repo, folder, nameToFind, filenames);

            resources = Optional.ofNullable(specificFile)
            .map(Arrays::asList)
            .orElse(loadFileBySuffix(client, repo, folder, suffixToFind, filenames));
            
            if (resources.isEmpty()) {
                resources = downloadFiles(client, repo, folder, filenames);
            }
        }

        List resourceNames = resources.stream().map(resource -> ((ConfigResource)resource).getName().concat(" ")).collect(Collectors.toList());

        log.info("Config files " + resourceNames + "\nwere found for repo: " + 
                repo.getRepoName() +
                " in folders: " + folders );
        
        return resources;
        
    }

    private SourceControlClient determineSourceControlClient() {
        SourceProviderType providerType = repoDto.getSourceProviderType();
        log.debug("Determining the client for the {} source control provider", providerType);

        Class clientClass = getClientClass(providerType);
        SourceControlClient result = getClientInstance(clientClass);

        log.debug("Using {} to access the repo", result.getClass().getName());
        return result;
    }

    private static SourceControlClient getClientInstance(Class clientClass) {
        SourceControlClient result;
        try {
            result = clientClass.getDeclaredConstructor().newInstance();
        } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
            String message = String.format("Unable to create an instance of %s.",
                    SourceProviderType.class.getSimpleName());
            throw new ConfigProviderException(message, e);
        }
        return result;
    }

    private static Class getClientClass(SourceProviderType sourceProviderType) {
        Class clientClass = sourceProviderMapping.get(sourceProviderType);
        if (clientClass == null) {
            String message = String.format("The '%s' %s is not supported",
                    sourceProviderType,
                    SourceProviderType.class.getSimpleName());
            throw new ConfigProviderException(message);
        }
        return clientClass;
    }

    private List downloadFiles(SourceControlClient client, RepoDto repo, String folder, List filenames)  {
        List resources = new LinkedList<>();
        if (filenames == null || filenames.isEmpty()) {
            throw new IllegalArgumentException("file names can not be empty");
        }
        filenames.stream().sorted().forEachOrdered(filename ->{
            String fileContent = client.downloadFileContent(folder, filename, repo);
            log.info("Config-as-code was found with content length: {}", fileContent.length());
            FileContentResource configResourceImpl = new FileContentResource(fileContent, filename);
            
            resources.add(configResourceImpl);
        });
        
        return resources;
    }


    private static void validate(RepoDto configLocation) {
         Objects.requireNonNull(configLocation, "Repository must not be null.");
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy