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

com.atlassian.bamboo.specs.maven.sandbox.SpecsRunner Maven / Gradle / Ivy

There is a newer version: 10.1.0
Show newest version
package com.atlassian.bamboo.specs.maven.sandbox;

import com.atlassian.bamboo.specs.api.rsbs.RunnerSettings;
import org.apache.maven.plugin.logging.Log;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.AccessControlException;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Supplier;
import java.util.stream.Collectors;

public class SpecsRunner {
    private final Log log;
    private final Collection classFiles;
    private final FileToBambooSpecsMapper fileToBambooSpecsMapper;
    private final ClassLoader classLoader;
    private final Set priorityClasspath;

    public SpecsRunner(final Log log, final Collection classFiles, final ClassLoader classloader, final Set priorityClasspath) {
        this.log = log;
        this.classFiles = classFiles;
        this.classLoader = classloader;
        this.priorityClasspath = priorityClasspath;
        this.fileToBambooSpecsMapper = new FileToBambooSpecsMapper(log, classloader);
    }

    public Map, Object> runSpecs(final boolean useSecurityManager) {
        if (useSecurityManager) {
            final ThreadPermissionVerifier permissionVerifier = new LowPrivilegeThreadPermissionVerifier(Paths.get("").toAbsolutePath(), RunnerSettings.getYamlDir());
            SecureMethodInvoker.startPerThreadSecurity(
                    customPermissionVerifiers(),
                    permissionVerifier);
            try {
                return SecureMethodInvoker.invoke(this::runSpecsInternal);
            } finally {
                SecureMethodInvoker.endPerThreadSecurity();
            }
        } else {
            return runSpecsInternal();
        }
    }

    @NotNull
    private Map customPermissionVerifiers() {
        final Map customVerfiers = new HashMap<>();
        try {
            final Class aClass = classLoader.loadClass("com.atlassian.bamboo.specs.util.PrivilegedThreadRegistry");
            final Field instance = aClass.getField("INSTANCE");
            final Supplier threadSupplier = (Supplier)instance.get(null);
            customVerfiers.put(threadSupplier.get(), new ReflectionEnabledThreadPermissionVerifier(classLoader, priorityClasspath));
            return customVerfiers;
        } catch (final Exception e) {
            throw new RuntimeException(e);
        }
    }

    @NotNull
    private Map, Object> runSpecsInternal() {
        final List> bambooSpecClasses = classFiles.stream()
                .map(fileToBambooSpecsMapper)
                .filter(Optional::isPresent)
                .map(Optional::get)
                .collect(Collectors.toList());

        for (final Class bambooSpecClass : bambooSpecClasses) {
            log.info("Running " + bambooSpecClass);
            callMainMethod(bambooSpecClass);
        }

        return Collections.emptyMap();
    }

    @Nullable
    private Object callMainMethod(final Class aClass) {
        final Method mainMethod = getMainMethod(aClass);
        if (mainMethod == null) {
            log.warn("No public static void main() method in " + aClass);
            return null;
        }

        final Object[] args = {
                new String[0]
        };

        try {
            return mainMethod.invoke(null, args);
        } catch (final InvocationTargetException | IllegalAccessException e) {
            if (e.getCause() instanceof AccessControlException) {
                throw (AccessControlException)e.getCause();
            }
            throw new RuntimeException(e);
        }
    }

    private static Method getMainMethod(final Class aClass) {
        try {
            return aClass.getMethod("main", String[].class);
        } catch (final NoSuchMethodException ignored) {
            return null;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy