com.sap.cds.services.runtime.ExtendedServiceLoader Maven / Gradle / Ivy
/**************************************************************************
* (C) 2019-2024 SAP SE or an SAP affiliate company. All rights reserved. *
**************************************************************************/
package com.sap.cds.services.runtime;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ServiceLoader;
/**
* Loads implementations of classes via Java's {@link ServiceLoader} and provides
* the {@link CdsRuntime} to these if requested through the {@link CdsRuntimeAware} interface.
*/
public class ExtendedServiceLoader {
/**
* Loads all implementations of the given class.
* The loaded implementations may NOT request the {@link CdsRuntime} through {@link CdsRuntimeAware}.
*
* @param the type
* @param clazz the class
* @return the implementations
*/
public static Iterator loadAll(Class clazz) {
return loadAll(clazz, null);
}
/**
* Loads all implementations of the given class.
* The loaded implementations may request the {@link CdsRuntime} through {@link CdsRuntimeAware}.
*
* @param the type
* @param clazz the class
* @param runtime the {@link CdsRuntime}
* @return the implementations, initialized with the {@link CdsRuntime}
*/
public static Iterator loadAll(Class clazz, CdsRuntime runtime) {
Iterator iterator = ServiceLoader.load(clazz).iterator();
List runtimeAware = new ArrayList<>();
iterator.forEachRemaining(i -> {
if(i instanceof CdsRuntimeAware aware) {
if(runtime == null) {
throw new IllegalStateException("Cannot provide CdsRuntime to implementation for " + clazz.getCanonicalName());
}
aware.setCdsRuntime(runtime);
}
runtimeAware.add(i);
});
return runtimeAware.iterator();
}
/**
* Loads the first implementation of the given class.
* The loaded implementation may NOT request the {@link CdsRuntime} through {@link CdsRuntimeAware}.
*
* @param the type
* @param clazz the class
* @return the implementation
*/
public static T loadSingle(Class clazz) {
return loadSingle(clazz, null);
}
/**
* Loads the first implementation of the given class.
* The loaded implementation may request the {@link CdsRuntime} through {@link CdsRuntimeAware}.
*
* @param the type
* @param clazz the class
* @param runtime the {@link CdsRuntime}
* @return the implementation, initialized with the {@link CdsRuntime}
*/
public static T loadSingle(Class clazz, CdsRuntime runtime) {
Iterator iterator = loadAll(clazz, runtime);
if (iterator.hasNext()) {
return iterator.next();
}
throw new IllegalStateException("Cannot find implementation for " + clazz.getCanonicalName());
}
}