package com.ematou.wxservice.common.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternUtils;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author lhm
 * @version 1.0
 * 2021-04-30 15:54
 */
@Component
public class CapturePackageClasses implements ResourceLoaderAware {

    private ResourceLoader resourceLoader;

    private static final Logger logger = LoggerFactory.getLogger(CapturePackageClasses.class);

    public List<Class<?>> getClass(String packageName) {

        List<Class<?>> classes = new ArrayList<>();

        packageName = packageName.replace('.' ,'/');

        ResourcePatternResolver resolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
        MetadataReaderFactory metaReader = new CachingMetadataReaderFactory(resourceLoader);
        Resource[] resources = new Resource[0];
        try {
            resources = resolver.getResources("classpath*:" + packageName + "/**/*.class");
        } catch (IOException e) {
            logger.error("包名格式不对！");
        }

        for (Resource resource : resources) {
            MetadataReader reader = null;
            try {
                reader = metaReader.getMetadataReader(resource);
            } catch (IOException e) {
                logger.error(e.getMessage());
            }
            assert reader != null : "reader为null！";
            classes.add(reader.getClass());
        }

        return classes;
    }

    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }
}
