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

com.quorum.tessera.serviceloader.ServiceLoaderExt Maven / Gradle / Ivy

There is a newer version: 21.4.1
Show newest version
package com.quorum.tessera.serviceloader;

import javax.inject.Singleton;
import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Stream;

public final class ServiceLoaderExt {

    private final ServiceLoader serviceLoader;

    private ServiceLoaderExt(ServiceLoader serviceLoader) {
        this.serviceLoader = serviceLoader;
    }

    public static  ServiceLoaderExt load(Class service, ClassLoader loader) {
        return new ServiceLoaderExt<>(ServiceLoader.load(service, loader));
    }

    public static  ServiceLoaderExt load(Class service) {
        return new ServiceLoaderExt<>(ServiceLoader.load(service));
    }

    public static  ServiceLoaderExt loadInstalled(Class service) {
        return new ServiceLoaderExt<>(ServiceLoader.loadInstalled(service));
    }

    public static  ServiceLoaderExt load(ModuleLayer layer, Class service) {
        return new ServiceLoaderExt<>(ServiceLoader.load(layer, service));
    }

    public Optional findFirst() {
        return serviceLoader.stream()
            .map(ServiceLoader.Provider::get)
            .findFirst();
    }

    public void reload() {
        serviceLoader.reload();
    }

    public void forEach(Consumer action) {
        stream()
            .map(ServiceLoader.Provider::get)
            .forEach(action);
    }

    public Spliterator spliterator() {
        return stream()
            .map(ServiceLoader.Provider::get)
            .spliterator();
    }

    public Iterator iterator() {
        return stream()
            .map(ServiceLoader.Provider::get)
            .iterator();
    }

    public Stream> stream() {
        return serviceLoader.stream()
            .map(ProviderExt::new);
    }

    private static class ProviderExt implements ServiceLoader.Provider {

        private final ServiceLoader.Provider provider;

        private static Object instance;

        private ProviderExt(final ServiceLoader.Provider provider) {
            this.provider = Objects.requireNonNull(provider);
        }

        @Override
        public Class type() {
            return provider.type();
        }

        @Override
        public S get() {
            if (type().isAnnotationPresent(Singleton.class)) {
                if (Objects.isNull(instance)) {
                    instance = provider.get();
                }
                return (S) instance;
            }

            return provider.get();
        }
    }
}