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

org.zodiac.plugin.factory.PluginRegistryInfo Maven / Gradle / Ivy

There is a newer version: 1.6.8
Show newest version
package org.zodiac.plugin.factory;

import org.pf4j.PluginManager;
import org.pf4j.PluginWrapper;
import org.pf4j.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
import org.zodiac.commons.util.Colls;
import org.zodiac.plugin.factory.process.pipe.PluginInfoContainers;
import org.zodiac.plugin.factory.process.pipe.loader.ResourceWrapper;
import org.zodiac.plugin.integration.IntegrationConfiguration;
import org.zodiac.plugin.realize.BasePlugin;
import org.zodiac.sdk.toolkit.util.collection.CollUtil;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * 注册的插件信息。
 */
public class PluginRegistryInfo {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    private final PluginWrapper pluginWrapper;
    private final PluginManager pluginManager;
    private final IntegrationConfiguration configuration;
    private final GenericApplicationContext mainApplicationContext;
    private final GenericApplicationContext pluginApplicationContext;
    private final Binder pluginBinder;
    private final SpringBeanRegister springBeanRegister;

    /**
     * 是否跟随主程序启动而初始化
     */
    private final boolean followingInitial;
    private final BasePlugin basePlugin;

    /**
     * 扩展存储项
     */
    private final Map extensionMap = CollUtil.concurrentMap();

    /**
     * 插件中的配置单例bean
     */
    private final Set configSingletonObjects = CollUtil.set(4);

    /**
     * 插件中的Class
     */
    private final List> classes = CollUtil.list(8);

    /**
     * 插件加载的资源
     */
    private final Map pluginLoadResources = CollUtil.concurrentMap(8);

    /**
     * 插件中分类的Class
     */
    private final Map>> groupClasses = CollUtil.concurrentMap(8);

    /**
     * 处理者信息
     */
    private final Map processorInfo = CollUtil.concurrentMap(8);

    protected PluginRegistryInfo(PluginWrapper pluginWrapper, PluginManager pluginManager,
        GenericApplicationContext mainApplicationContext, boolean followingInitial) {
        this.pluginWrapper = pluginWrapper;
        this.pluginManager = pluginManager;
        this.basePlugin = (BasePlugin)pluginWrapper.getPlugin();
        this.mainApplicationContext = mainApplicationContext;
        this.configuration = mainApplicationContext.getBean(IntegrationConfiguration.class);
        this.followingInitial = followingInitial;

        ClassLoader pluginClassLoader = basePlugin.getWrapper().getPluginClassLoader();
        this.pluginApplicationContext = obtainPluginApplicationContext();
        // 设置插件ApplicationContext的classLoader
        this.pluginApplicationContext.setClassLoader(pluginClassLoader);

        this.pluginBinder = Binder.get(this.pluginApplicationContext.getEnvironment());
        this.springBeanRegister = new SpringBeanRegister(pluginApplicationContext);
    }

    public static PluginRegistryInfo build(PluginWrapper pluginWrapper, PluginManager pluginManager,
        GenericApplicationContext parentApplicationContext, boolean followingInitial) {
        Objects.requireNonNull(pluginWrapper, "PluginWrapper can't is null");
        Objects.requireNonNull(pluginManager, "PluginManager can't is null");
        Objects.requireNonNull(parentApplicationContext, "parentApplicationContext can't is null");
        return new PluginRegistryInfo(pluginWrapper, pluginManager, parentApplicationContext, followingInitial);
    }

    public PluginWrapper getPluginWrapper() {
        return pluginWrapper;
    }

    public BasePlugin getBasePlugin() {
        return basePlugin;
    }

    /**
     * 添加类到类集合容器
     * 
     * @param aClass
     *            类
     */
    public void addClasses(Class aClass) {
        if (aClass != null) {
            classes.add(aClass);
        }
    }

    /**
     * 清除类集合容器
     */
    public void cleanClasses() {
        classes.clear();
    }

    /**
     * 得到类集合容器
     * 
     * @return 类集合容器
     */
    public List> getClasses() {
        return Collections.unmodifiableList(classes);
    }

    /**
     * 添加插件中加载的资源
     * 
     * @param key
     *            key
     * @param resourceWrapper
     *            资源包装者
     */
    public void addPluginLoadResource(String key, ResourceWrapper resourceWrapper) {
        if (StringUtils.isNullOrEmpty(key)) {
            return;
        }
        if (resourceWrapper == null) {
            return;
        }
        pluginLoadResources.put(key, resourceWrapper);
    }

    /**
     * 得到插件中加载的资源
     * 
     * @param key
     *            资源key
     * @return ResourceWrapper
     */
    public ResourceWrapper getPluginLoadResource(String key) {
        return pluginLoadResources.get(key);
    }

    /**
     * 添加分组的类型
     * 
     * @param key
     *            分组key
     * @param aClass
     *            类
     */
    public void addGroupClasses(String key, Class aClass) {
        if (StringUtils.isNullOrEmpty(key)) {
            return;
        }
        if (aClass == null) {
            return;
        }
        List> classes = groupClasses.computeIfAbsent(key, k -> CollUtil.list());
        classes.add(aClass);
    }

    /**
     * 通过分组key得到分组中的类类型
     * 
     * @param key
     *            处理者key
     * @return 类类型集合
     */
    public List> getGroupClasses(String key) {
        List> classes = groupClasses.get(key);
        List> result = CollUtil.list();
        if (classes != null) {
            result.addAll(classes);
        }
        return result;
    }

    /**
     * 得到插件bean注册者信息
     * 
     * @param key
     *            扩展的key
     * @param 
     *            处理者类型
     * @return 注册者信息
     */
    public  T getProcessorInfo(String key) {
        Object o = processorInfo.get(key);
        if (o != null) {
            return (T)o;
        }
        return null;
    }

    /**
     * 添加插件中的配置对象
     * 
     * @param singletonObject
     *            单例对象
     */
    public void addConfigSingleton(Object singletonObject) {
        configSingletonObjects.add(singletonObject);
    }

    /**
     * 添加插件中的配置对象
     * 
     * @return 配置的实现对象
     */
    public Set getConfigSingletons() {
        return Collections.unmodifiableSet(configSingletonObjects);
    }

    /**
     * 添加处理者信息
     * 
     * @param key
     *            key
     * @param value
     *            value
     */
    public void addProcessorInfo(String key, Object value) {
        processorInfo.put(key, value);
    }

    /**
     * 添加扩展数据
     * 
     * @param key
     *            扩展的key
     * @param value
     *            扩展值
     */
    public void addExtension(String key, Object value) {
        if (extensionMap.containsKey(key)) {
            throw new RuntimeException("The extension key ' " + key + " 'already exists");
        }
        extensionMap.put(key, value);
    }

    /**
     * 得到主程序的ApplicationContext
     * 
     * @return GenericApplicationContext
     */
    public GenericApplicationContext getMainApplicationContext() {
        return mainApplicationContext;
    }

    /**
     * 得到当前插件的ApplicationContext
     * 
     * @return AnnotationConfigApplicationContext
     */
    public GenericApplicationContext getPluginApplicationContext() {
        return pluginApplicationContext;
    }

    /**
     * 得到当前插件的Binder
     * 
     * @return Binder
     */
    public Binder getPluginBinder() {
        return pluginBinder;
    }

    /**
     * 得到当前插件Bean注册者
     * 
     * @return SpringBeanRegister
     */
    public SpringBeanRegister getSpringBeanRegister() {
        return springBeanRegister;
    }

    /**
     * 移除扩展数据
     * 
     * @param key
     *            扩展的key
     */
    public void removeExtension(String key) {
        extensionMap.remove(key);
    }

    /**
     * 获取扩展值
     * 
     * @param key
     *            扩展的key
     * @param 
     *            返回值泛型
     * @return 扩展值
     */
    public  T getExtension(String key) {
        Object o = extensionMap.get(key);
        if (o == null) {
            return null;
        } else {
            return (T)o;
        }
    }

    public ClassLoader getPluginClassLoader() {
        return pluginWrapper.getPluginClassLoader();
    }

    public boolean isFollowingInitial() {
        return followingInitial;
    }

    public IntegrationConfiguration getConfiguration() {
        return configuration;
    }

    protected GenericApplicationContext obtainPluginApplicationContext() {
        /*生成插件ApplicationContext-DefaultListableBeanFactory*/
        DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();
        GenericApplicationContext pluginApplicationContext = new AnnotationConfigApplicationContext(defaultListableBeanFactory);
        return pluginApplicationContext;
    }

    void destroy() {
        // 关闭ApplicationContext
        try {
            PluginInfoContainers.removePluginApplicationContext(getPluginWrapper().getPluginId());
            closePluginApplicationContext();
        } catch (Exception e) {
            logger.error("Close plugin '{}'-ApplicationContext failure", getPluginWrapper().getPluginId(), e);
        }

        // 清除数据集合
        try {
            extensionMap.clear();
            classes.clear();
            groupClasses.clear();
            processorInfo.clear();
            pluginLoadResources.clear();
            configSingletonObjects.clear();
        } catch (Exception e) {
            logger.error("Clear plugin '{}' failure", getPluginWrapper().getPluginId(), e);
        }
    }

    private void closePluginApplicationContext() {
        try {
            getSpringBeanRegister().destroySingletons();
            pluginApplicationContext.close();
        } catch (Exception e) {
            logger.error("Close plugin '{}' ApplicationContext failure", getPluginWrapper().getPluginId(), e);
        }
    }

}