/*
 * Decompiled with CFR 0.152.
 */
package org.apache.logging.log4j.core.util;

import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ReflectPermission;
import java.net.URL;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.util.OptionConverter;
import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.util.LoaderUtil;
import org.apache.logging.log4j.util.PropertiesUtil;

public final class Loader {
    private static boolean ignoreTCL;
    private static final Logger LOGGER;
    private static final String TSTR = "Caught Exception while in Loader.getResource. This may be innocuous.";

    public static ClassLoader getClassLoader() {
        return Loader.getClassLoader(Loader.class, null);
    }

    public static ClassLoader getThreadContextClassLoader() {
        return LoaderUtil.getThreadContextClassLoader();
    }

    public static ClassLoader getClassLoader(Class<?> class1, Class<?> class2) {
        ClassLoader loader2;
        ClassLoader threadContextClassLoader = null;
        try {
            threadContextClassLoader = Loader.getTcl();
        }
        catch (Exception ex) {
            LOGGER.warn("Caught exception locating thread ClassLoader {}", ex.getMessage());
        }
        ClassLoader loader1 = class1 == null ? null : class1.getClassLoader();
        ClassLoader classLoader = loader2 = class2 == null ? null : class2.getClassLoader();
        if (Loader.isChild(threadContextClassLoader, loader1)) {
            return Loader.isChild(threadContextClassLoader, loader2) ? threadContextClassLoader : loader2;
        }
        return Loader.isChild(loader1, loader2) ? loader1 : loader2;
    }

    public static URL getResource(String resource, ClassLoader defaultLoader) {
        try {
            URL url;
            ClassLoader classLoader = Loader.getTcl();
            if (classLoader != null) {
                LOGGER.trace("Trying to find [{}] using context class loader {}.", resource, classLoader);
                url = classLoader.getResource(resource);
                if (url != null) {
                    return url;
                }
            }
            if ((classLoader = Loader.class.getClassLoader()) != null) {
                LOGGER.trace("Trying to find [{}] using {} class loader.", resource, classLoader);
                url = classLoader.getResource(resource);
                if (url != null) {
                    return url;
                }
            }
            if (defaultLoader != null) {
                LOGGER.trace("Trying to find [{}] using {} class loader.", resource, defaultLoader);
                url = defaultLoader.getResource(resource);
                if (url != null) {
                    return url;
                }
            }
        }
        catch (Throwable t) {
            LOGGER.warn(TSTR, t);
        }
        LOGGER.trace("Trying to find [{}] using ClassLoader.getSystemResource().", resource);
        return ClassLoader.getSystemResource(resource);
    }

    public static InputStream getResourceAsStream(String resource, ClassLoader defaultLoader) {
        try {
            InputStream is;
            ClassLoader classLoader = Loader.getTcl();
            if (classLoader != null) {
                LOGGER.trace("Trying to find [{}] using context class loader {}.", resource, classLoader);
                is = classLoader.getResourceAsStream(resource);
                if (is != null) {
                    return is;
                }
            }
            if ((classLoader = Loader.class.getClassLoader()) != null) {
                LOGGER.trace("Trying to find [{}] using {} class loader.", resource, classLoader);
                is = classLoader.getResourceAsStream(resource);
                if (is != null) {
                    return is;
                }
            }
            if (defaultLoader != null) {
                LOGGER.trace("Trying to find [{}] using {} class loader.", resource, defaultLoader);
                is = defaultLoader.getResourceAsStream(resource);
                if (is != null) {
                    return is;
                }
            }
        }
        catch (Throwable t) {
            LOGGER.warn(TSTR, t);
        }
        LOGGER.trace("Trying to find [{}] using ClassLoader.getSystemResource().", resource);
        return ClassLoader.getSystemResourceAsStream(resource);
    }

    private static ClassLoader getTcl() {
        return LoaderUtil.getThreadContextClassLoader();
    }

    private static boolean isChild(ClassLoader loader1, ClassLoader loader2) {
        if (loader1 != null && loader2 != null) {
            ClassLoader parent;
            for (parent = loader1.getParent(); parent != null && parent != loader2; parent = parent.getParent()) {
            }
            return parent != null;
        }
        return loader1 != null;
    }

    public static Class<?> loadClass(String className) throws ClassNotFoundException {
        if (ignoreTCL) {
            LOGGER.trace("Ignoring TCCL. Trying Class.forName({}).", className);
            return Loader.loadClassWithDefaultClassLoader(className);
        }
        try {
            LOGGER.trace("Trying TCCL for class {}.", className);
            return Class.forName(className, true, Loader.getTcl());
        }
        catch (Throwable e) {
            LOGGER.trace("TCCL didn't work for class {}: {}.", className, e.toString());
            return Loader.loadClassWithDefaultClassLoader(className);
        }
    }

    private static Class<?> loadClassWithDefaultClassLoader(String className) throws ClassNotFoundException {
        return Class.forName(className);
    }

    public static Class<?> initializeClass(String className, ClassLoader loader) throws ClassNotFoundException {
        return Class.forName(className, true, loader);
    }

    public static Class<?> loadSystemClass(String className) throws ClassNotFoundException {
        try {
            return Class.forName(className, true, ClassLoader.getSystemClassLoader());
        }
        catch (Throwable t) {
            LOGGER.trace("Couldn't use SystemClassLoader. Trying Class.forName({}).", className, t);
            return Class.forName(className);
        }
    }

    public static Object newInstanceOf(String className) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class<?> clazz = Loader.loadClass(className);
        try {
            return clazz.getConstructor(new Class[0]).newInstance(new Object[0]);
        }
        catch (NoSuchMethodException e) {
            return clazz.newInstance();
        }
    }

    public static <T> T newCheckedInstanceOf(String className, Class<T> clazz) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        return clazz.cast(Loader.newInstanceOf(className));
    }

    public static boolean isClassAvailable(String className) {
        try {
            Class<?> clazz = Loader.loadClass(className);
            return clazz != null;
        }
        catch (ClassNotFoundException e) {
            return false;
        }
        catch (Throwable e) {
            LOGGER.trace("Unknown error checking for existence of class [{}].", className, e);
            return false;
        }
    }

    private Loader() {
    }

    static {
        SecurityManager sm;
        ignoreTCL = false;
        LOGGER = StatusLogger.getLogger();
        String ignoreTCLProp = PropertiesUtil.getProperties().getStringProperty("log4j.ignoreTCL", null);
        if (ignoreTCLProp != null) {
            ignoreTCL = OptionConverter.toBoolean(ignoreTCLProp, true);
        }
        if ((sm = System.getSecurityManager()) != null) {
            sm.checkPermission(new RuntimePermission("getStackTrace"));
            sm.checkPermission(new ReflectPermission("suppressAccessChecks"));
        }
    }
}
