com.daiyc.extension.core.ExtensionContext Maven / Gradle / Ivy
package com.daiyc.extension.core;
import com.daiyc.extension.core.annotations.ExtensionPoint;
import com.daiyc.extension.core.impl.ExtensionLoaderImpl;
import com.daiyc.extension.core.impl.ExtensionRegistryImpl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;
import java.util.stream.Collectors;
/**
* @author daiyc
* @since 2024/7/27
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public class ExtensionContext implements ExtensionLoaderFactory, ExtensionPointRegistry {
protected final Map, ExtensionLoader>> loaders = new ConcurrentHashMap<>();
protected final Map, ExtensionRegistry>> registries = new ConcurrentHashMap<>();
@Override
public ExtensionLoader getExtensionLoader(Class clazz) {
ExtensionRegistry> extensionRegistry = registries.computeIfAbsent(clazz, ExtensionRegistryImpl::new);
return (ExtensionLoader) loaders.computeIfAbsent(clazz, t ->
new ExtensionLoaderImpl<>(clazz, (ExtensionRegistry) extensionRegistry));
}
@Override
public void register(Class clazz) {
register(clazz, (Supplier) () -> {
try {
return clazz.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new RuntimeException(e);
}
});
}
@Override
public void register(Class clazz, I ext) {
register(clazz, (Supplier) () -> ext);
}
@Override
public void register(Class clazz, Supplier supplier) {
List> points = parseExtensionPoints(clazz);
for (Class point : points) {
doRegister(point, clazz, supplier);
}
}
private List> parseExtensionPoints(Class clazz) {
List> points = new ArrayList<>();
Class> p = clazz;
while (!p.equals(Object.class)) {
List> eps = Arrays.stream(p.getInterfaces())
.filter(type -> type.isAnnotationPresent(ExtensionPoint.class))
.collect(Collectors.toList());
points.addAll(eps);
p = p.getSuperclass();
}
return points;
}
protected void doRegister(Class interfaze, Class clazz, Supplier supplier) {
ExtensionRegistry> extensionRegistry = registries.computeIfAbsent(interfaze, ExtensionRegistryImpl::new);
extensionRegistry.register((Class) clazz, (Supplier) supplier);
}
}