Package com.baidu.disconf.client.scan.inner.statically

Source Code of com.baidu.disconf.client.scan.inner.statically.ScanStatic

package com.baidu.disconf.client.scan.inner.statically;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.reflections.Reflections;
import org.reflections.scanners.FieldAnnotationsScanner;
import org.reflections.scanners.MethodAnnotationsScanner;
import org.reflections.scanners.MethodParameterScanner;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.scanners.TypeAnnotationsScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import org.reflections.util.FilterBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.baidu.disconf.client.common.annotations.DisconfActiveBackupService;
import com.baidu.disconf.client.common.annotations.DisconfFile;
import com.baidu.disconf.client.common.annotations.DisconfFileItem;
import com.baidu.disconf.client.common.annotations.DisconfItem;
import com.baidu.disconf.client.common.annotations.DisconfUpdateService;
import com.baidu.disconf.client.common.constants.Constants;
import com.baidu.disconf.client.scan.inner.common.ScanVerify;
import com.baidu.disconf.client.scan.inner.statically.model.ScanStaticModel;
import com.google.common.base.Predicate;

/**
*
* 扫描静态注解,并且进行分析整合数据
*
* @author liaoqiqi
* @version 2014-6-6
*/
public class ScanStatic {

    protected static final Logger LOGGER = LoggerFactory
            .getLogger(ScanStatic.class);

    /**
     * 通过扫描,获取反射对象
     *
     * @param packName
     * @return
     */
    private static Reflections getReflection(String packName) {

        Predicate<String> filter = new FilterBuilder().includePackage(
                Constants.DISCONF_PACK_NAME).includePackage(packName);

        //
        Reflections reflections = new Reflections(new ConfigurationBuilder()
                .filterInputsBy(filter)
                .setScanners(new SubTypesScanner().filterResultsBy(filter),
                        new TypeAnnotationsScanner().filterResultsBy(filter),
                        new FieldAnnotationsScanner().filterResultsBy(filter),
                        new MethodAnnotationsScanner().filterResultsBy(filter),
                        new MethodParameterScanner())
                .setUrls(ClasspathHelper.forPackage(packName)));

        return reflections;
    }

    /**
     * 扫描想要的类
     *
     * @return
     */
    public static ScanStaticModel scan(String packName) {

        // 基本信息
        ScanStaticModel scanModel = scanBasicInfo(packName);

        // 分析
        analysis(scanModel);

        return scanModel;
    }

    /**
     * 分析出一些关系 出来
     *
     * @param scanModel
     */
    private static void analysis(ScanStaticModel scanModel) {

        // 分析出配置文件MAP
        analysis4DisconfFile(scanModel);
    }

    /**
     * 分析出配置文件与配置文件中的Field的Method的MAP
     *
     * @param scanModel
     */
    private static void analysis4DisconfFile(ScanStaticModel scanModel) {

        Map<Class<?>, Set<Method>> disconfFileItemMap = new HashMap<Class<?>, Set<Method>>();

        //
        // 配置文件MAP
        //
        Set<Class<?>> classdata = scanModel.getDisconfFileClassSet();
        for (Class<?> classFile : classdata) {
            disconfFileItemMap.put(classFile, new HashSet<Method>());
        }

        //
        // 将配置文件与配置文件中的配置项进行关联
        //
        Set<Method> af1 = scanModel.getDisconfFileItemMethodSet();
        for (Method method : af1) {

            Class<?> thisClass = method.getDeclaringClass();

            if (disconfFileItemMap.containsKey(thisClass)) {
                Set<Method> fieldSet = disconfFileItemMap.get(thisClass);
                fieldSet.add(method);
                disconfFileItemMap.put(thisClass, fieldSet);

            } else {

                LOGGER.error("cannot find CLASS ANNOTATION "
                        + DisconfFile.class.getName()
                        + " for disconf file item: " + method.toString());
            }
        }

        //
        // 最后的校验
        //
        Iterator<Class<?>> iterator = disconfFileItemMap.keySet().iterator();
        while (iterator.hasNext()) {

            Class<?> classFile = iterator.next();

            // 校验是否所有配置文件都含有配置
            if (disconfFileItemMap.get(classFile).isEmpty()) {
                LOGGER.warn("disconf file hasn't any items: "
                        + classFile.getName());
                continue;
            }

            // 校验配置文件类型是否合适(目前只支持.properties类型)
            DisconfFile disconfFile = (DisconfFile) classFile
                    .getAnnotation(DisconfFile.class);
            boolean fileTypeRight = ScanVerify
                    .isDisconfFileTypeRight(disconfFile);
            if (!fileTypeRight) {
                LOGGER.warn("now do not support NOT .properties file"
                        + disconfFile.toString());
                continue;
            }
        }

        // 设置
        scanModel.setDisconfFileItemMap(disconfFileItemMap);
    }

    /**
     * 扫描基本信息
     *
     * @return
     */
    private static ScanStaticModel scanBasicInfo(String packName) {

        ScanStaticModel scanModel = new ScanStaticModel();

        //
        // 扫描对象
        //
        Reflections reflections = getReflection(packName);
        scanModel.setReflections(reflections);

        //
        // 获取DisconfFile class
        //
        Set<Class<?>> classdata = reflections
                .getTypesAnnotatedWith(DisconfFile.class);
        scanModel.setDisconfFileClassSet(classdata);

        //
        // 获取DisconfFileItem method
        //
        Set<Method> af1 = reflections
                .getMethodsAnnotatedWith(DisconfFileItem.class);
        scanModel.setDisconfFileItemMethodSet(af1);

        //
        // 获取DisconfItem method
        //
        af1 = reflections.getMethodsAnnotatedWith(DisconfItem.class);
        scanModel.setDisconfItemMethodSet(af1);

        //
        // 获取DisconfActiveBackupService
        //
        classdata = reflections
                .getTypesAnnotatedWith(DisconfActiveBackupService.class);
        scanModel.setDisconfActiveBackupServiceClassSet(classdata);

        //
        // 获取DisconfUpdateService
        //
        classdata = reflections
                .getTypesAnnotatedWith(DisconfUpdateService.class);
        scanModel.setDisconfUpdateService(classdata);

        return scanModel;
    }

}
TOP

Related Classes of com.baidu.disconf.client.scan.inner.statically.ScanStatic

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.