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

com.jaemon.dingtalk.multi.MultiDingerScannerRegistrar Maven / Gradle / Ivy

There is a newer version: 3.1.2-RELEASE
Show newest version
/*
 * Copyright 2015-2020 Jaemon([email protected])
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.jaemon.dingtalk.multi;

import com.jaemon.dingtalk.dinger.DingerConfig;
import com.jaemon.dingtalk.exception.DingTalkException;
import com.jaemon.dingtalk.listeners.ApplicationEventTimeTable;
import com.jaemon.dingtalk.multi.algorithm.AlgorithmHandler;
import com.jaemon.dingtalk.multi.annotations.EnableMultiDinger;
import com.jaemon.dingtalk.multi.annotations.MultiHandler;
import com.jaemon.dingtalk.multi.entity.MultiDingerConfig;
import com.jaemon.dingtalk.utils.DingTalkUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.objenesis.instantiator.util.ClassUtils;

import java.util.List;
import java.util.stream.Collectors;

import static com.jaemon.dingtalk.entity.enums.ExceptionEnum.GLOBAL_MULTIDINGER_CONFIG_EXCEPTION;
import static com.jaemon.dingtalk.entity.enums.ExceptionEnum.MULTIDINGER_ALGORITHM_EXCEPTION;
import static com.jaemon.dingtalk.multi.MultiDingerConfigContainer.GLOABL_KEY;

/**
 * MultiDingerScannerRegistrar
 *
 * @author Jaemon#[email protected]
 * @since 3.0
 */
public class MultiDingerScannerRegistrar implements ImportBeanDefinitionRegistrar, Ordered {
    private static final Logger log = LoggerFactory.getLogger(MultiDingerScannerRegistrar.class);
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        boolean debugEnabled = log.isDebugEnabled();
        log.info("ready to execute multiDingerScanner...");

        try {
            if (!importingClassMetadata.hasAnnotation(EnableMultiDinger.class.getName())) {
                log.warn("import class can't find EnableMultiDinger annotation.");
                return;
            }

            AnnotationAttributes annotationAttributes = AnnotationAttributes.fromMap(
                    importingClassMetadata.getAnnotationAttributes(EnableMultiDinger.class.getName())
            );

            Class value = annotationAttributes.getClass("value");
            if (value.isInterface()) {
                if (DingerConfigHandler.class.equals(value)) {
                    // 处理需要执行MultiDinger逻辑的dingerClass
                    List> dingerClasses = ApplicationEventTimeTable.dingerClasses();
                    if (dingerClasses.isEmpty()) {
                        log.warn("dinger class is empty, so don't deal with multiDinger.");
                        return;
                    }

                    cacheMultiDingerItc(dingerClasses);

                    if (!MultiDingerConfigContainer.INSTANCE.isEmpty()) {
                        MultiDingerProperty.multiDinger = true;
                    }
                } else {
                    throw new DingTalkException(GLOBAL_MULTIDINGER_CONFIG_EXCEPTION);
                }

            } else {
                if (debugEnabled) {
                    log.debug("enable global multi dinger, and multiDinger handler class={}.", value.getName());
                }
                DingerConfigHandler dingerConfigHandler = BeanUtils.instantiateClass(value);
                registerHandler(GLOABL_KEY, dingerConfigHandler);
                MultiDingerProperty.multiDinger = true;
            }

        } finally {
            ApplicationEventTimeTable.emptyDingerClasses();
        }

    }


    /**
     * cacheMultiDingerItc
     *
     * @param dingerClasses             dingerClasses
     */
    private void cacheMultiDingerItc(List> dingerClasses) {
        boolean debugEnabled = log.isDebugEnabled();

        for (Class dingerClass : dingerClasses) {
            if (dingerClass.isAnnotationPresent(MultiHandler.class)) {
                if (debugEnabled) {
                    log.debug("dingerClass={} configured with MultiDinger annotation.", dingerClass.getSimpleName());
                }
                MultiHandler multiDinger = dingerClass.getAnnotation(MultiHandler.class);
                Class dingerConfigHandler = multiDinger.value();
                String beanName = dingerConfigHandler.getSimpleName();
                if (dingerConfigHandler.isInterface()) {
                    log.warn("dingerClass={}  handler className={} is interface and skip.",
                            dingerClass.getSimpleName(), beanName);
                    continue;
                }
                String key = dingerClass.getName();
                DingerConfigHandler handler = ClassUtils.newInstance(dingerConfigHandler);

                registerHandler(key, handler);
            }
        }
    }


    /**
     * 注册 handler
     *
     * @param key                   key
     * @param dingerConfigHandler   dingerConfigHandler
     */
    private void registerHandler(String key, DingerConfigHandler dingerConfigHandler) {
        Class algorithm = dingerConfigHandler.algorithmHandler();
        // if empty? use default dinger config
        List dingerConfigs = dingerConfigHandler.dingerConfigs();

        if (algorithm == null) {
            throw new DingTalkException(MULTIDINGER_ALGORITHM_EXCEPTION);
        }

        // create algorithm instance
        AlgorithmHandler algorithmHandler = ClassUtils.newInstance(algorithm);

        // check dingerConfig
        List dcs =
                dingerConfigs
                        .stream()
                        .filter(
                                e -> DingTalkUtils.isNotEmpty(
                                        e.getTokenId()
                                )
                        )
                        .collect(Collectors.toList());
        // save into memory
        MultiDingerConfigContainer.INSTANCE.put(
                key, new MultiDingerConfig(algorithmHandler, dcs)
        );
        log.info("multiDinger key={}, dingerConfigHandler class={}, dingerConfigs={}, valid dingerConfigs={}.",
                key, dingerConfigHandler.getClass().getSimpleName(), dingerConfigs.size(), dcs.size());
    }


    @Override
    public int getOrder() {
        return LOWEST_PRECEDENCE - 1;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy