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

com.microsoft.semantickernel.implementation.ServiceLoadUtil Maven / Gradle / Ivy

There is a newer version: 1.3.0
Show newest version
// Copyright (c) Microsoft. All rights reserved.
package com.microsoft.semantickernel.implementation;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ServiceLoader;
import java.util.function.Supplier;
import com.microsoft.semantickernel.localization.SemanticKernelResources;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * This class is used for loading services that are not directly referenced in the code, but are
 * instead loaded using the ServiceLoader pattern.
 */
public class ServiceLoadUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(ServiceLoadUtil.class);

    private ServiceLoadUtil() {
    }

    /**
     * Finds a service loader for the given class and returns a supplier for it.
     *
     * @param clazz                The class to find a service loader for.
     * @param                   The type of the class to find a service loader for.
     * @param alternativeClassName The name of the alternative class to load if the service loader
     *                             is not found.
     * @return A {@code java.util.function.Supplier} for the service loader.
     */
    public static  Supplier findServiceLoader(Class clazz, String alternativeClassName) {
        List services = findAllServiceLoaders(clazz);

        T impl = null;

        if (!services.isEmpty()) {
            impl = services.get(0);
        }

        if (impl == null) {
            try {
                // Service loader not found, attempt to load the alternative class
                Object instance = Class.forName(alternativeClassName).getDeclaredConstructor()
                    .newInstance();
                if (clazz.isInstance(instance)) {
                    impl = (T) instance;
                }
            } catch (ClassNotFoundException
                | InvocationTargetException
                | InstantiationException
                | IllegalAccessException
                | NoSuchMethodException
                | RuntimeException e) {
                LOGGER.error(String.format(
                    SemanticKernelResources.getString("unable.to.load.service.s"), clazz.getName()),
                    e);
            }

            if (impl == null) {
                throw new RuntimeException(String.format("Service not found: %s", clazz.getName()));
            }
        }

        try {
            Constructor constructor = impl.getClass().getConstructor();

            // Test that we can construct the builder
            if (!clazz.isInstance(constructor.newInstance())) {
                throw new RuntimeException(
                    "Builder creates instance of the wrong type: " + clazz.getName());
            }

            return () -> {
                try {
                    return (T) constructor.newInstance();
                } catch (InstantiationException
                    | IllegalAccessException
                    | InvocationTargetException e) {
                    throw new RuntimeException(e);
                }
            };
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(
                "Builder requires a no args constructor: " + clazz.getName());
        } catch (InvocationTargetException | InstantiationException | IllegalAccessException e) {
            throw new RuntimeException("Builder is of wrong type: " + clazz.getName());
        }
    }

    static  List findAllServiceLoaders(Class clazz) {
        List serviceLoaders = new ArrayList();

        ServiceLoader factory = ServiceLoader.load(clazz);
        Iterator iterator = factory.iterator();
        iterator.forEachRemaining(serviceLoaders::add);

        return serviceLoaders;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy