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

jakarta.enterprise.inject.build.compatible.spi.BuildServicesResolver Maven / Gradle / Ivy

/*
 * Copyright (c) 2021 Red Hat and others
 *
 * This program and the accompanying materials are made available under the
 * Apache Software License 2.0 which is available at:
 * https://www.apache.org/licenses/LICENSE-2.0.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

package jakarta.enterprise.inject.build.compatible.spi;

import java.util.Collections;
import java.util.Comparator;
import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.TreeSet;

/**
 * An internal helper to resolve {@link BuildServices} implementations.
 * This class is public only for integrators and should not be used by applications.
 *
 * @since 4.0
 */
public final class BuildServicesResolver {
    private static final Object lock = new Object();
    private static volatile Set discoveredBuildServices;
    private static volatile BuildServices configuredBuildServices;

    static BuildServices get() {
        if (configuredBuildServices != null) {
            return configuredBuildServices;
        }

        if (discoveredBuildServices == null) {
            synchronized (lock) {
                if (discoveredBuildServices == null) {
                    discoverFactories();
                }
            }
        }

        configuredBuildServices = discoveredBuildServices.iterator().next();

        return configuredBuildServices;
    }

    private static void discoverFactories() {
        Set factories = new TreeSet<>(
                Comparator.comparingInt(BuildServices::getPriority).reversed());

        ServiceLoader loader = SecurityActions.loadService(
                BuildServices.class, BuildServicesResolver.class.getClassLoader());

        if (!loader.iterator().hasNext()) {
            throw new IllegalStateException("Unable to locate BuildServices implementation");
        }

        try {
            for (BuildServices buildServicies : loader) {
                factories.add(buildServicies);
            }
        } catch (ServiceConfigurationError e) {
            throw new IllegalStateException(e);
        }

        BuildServicesResolver.discoveredBuildServices = Collections.unmodifiableSet(factories);
    }

    /**
     * This method should not be used by applications. It is only exposed for integrators
     * with complex classloading architectures, where service loader lookup doesn't work out of the box.
     * With this method, an integrator may manually provide an instance of {@link BuildServices} and
     * this class will no longer attempt to look it up using service loader.
     *
     * @param instance a {@link BuildServices} instance that should be used, must not be {@code null}
     * @throws IllegalArgumentException if the provided argument is null
     */
    public static void setBuildServices(BuildServices instance) {
        if (instance == null) {
            throw new IllegalArgumentException("BuildServices instance must not be null");
        }
        configuredBuildServices = instance;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy