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

com.daiyc.extension.core.ExtensionContext Maven / Gradle / Ivy

There is a newer version: 1.3.2
Show newest version
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);
    }
}