com.taotao.boot.dingtalk.model.ClassPathScanForResources Maven / Gradle / Ivy
/*
* Copyright (c) 2020-2030, Shuigedeng ([email protected] & https://blog.taotaocloud.top/).
*
* 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
*
* https://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.taotao.boot.dingtalk.model;
import com.taotao.boot.common.utils.log.LogUtils;
import com.taotao.boot.dingtalk.exception.DingerException;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.SimpleMetadataReaderFactory;
import org.springframework.util.ClassUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import static com.taotao.boot.dingtalk.enums.ExceptionEnum.RESOURCE_CONFIG_EXCEPTION;
/**
* ClassPathScanForResources
*
* @author shuigedeng
* @version 2022.07
* @since 2022-07-06 15:22:20
*/
public final class ClassPathScanForResources {
private static final String CLASSPATH_ALL_URL_PREFIX = "classpath*:";
private static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";
private static final ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
/**
* 扫描包
*
* @param packageSearchPath 扫描的包路径, classpath*:com.jaemon.dinger/**\/*.class
* @return 包下的所有资源文件集
*/
public static Resource[] doScanPackage(String packageSearchPath) {
try {
return resolver.getResources(packageSearchPath);
} catch (IOException ex) {
LogUtils.error(packageSearchPath, ex);
throw new DingerException(RESOURCE_CONFIG_EXCEPTION, packageSearchPath);
}
}
/**
* @param basePackage 包名, eg: com.jaemon.dinger
* @return 包下的所有接口集合
*/
public static List> scanInterfaces(String basePackage) {
return scanClasses(basePackage, true);
}
/**
* @param basePackage 包名, eg: com.jaemon.dinger
* @return 包下的所有类集合
*/
public static List> scanClasses(String basePackage) {
return scanClasses(basePackage, false);
}
/**
* @param basePackage 包名, eg: com.jaemon.dinger
* @param filterInterface 是否过滤接口
* @return 包下的所有类集合
*/
private static List> scanClasses(String basePackage, boolean filterInterface) {
String packageSearchPath =
CLASSPATH_ALL_URL_PREFIX + resolveBasePackage(basePackage) + "/" + DEFAULT_RESOURCE_PATTERN;
Resource[] resources = doScanPackage(packageSearchPath);
List> classes = new ArrayList<>();
if (resources.length == 0) {
return classes;
}
SimpleMetadataReaderFactory factory = new SimpleMetadataReaderFactory();
for (Resource resource : resources) {
String resourceFilename = resource.getFilename();
if (!resource.isReadable()) {
LogUtils.debug("Ignored because not readable: {} ", resourceFilename);
continue;
}
try {
MetadataReader metadataReader = factory.getMetadataReader(resource);
ClassMetadata classMetadata = metadataReader.getClassMetadata();
Class> clazz = Class.forName(classMetadata.getClassName());
if (filterInterface && !clazz.isInterface()) {
LogUtils.debug("source class={} is interface and skip.", resourceFilename);
continue;
}
classes.add(clazz);
} catch (IOException | ClassNotFoundException e) {
LogUtils.warn("resource={} read exception and message={}.", resourceFilename, e.getMessage());
continue;
}
}
return classes;
}
private static String resolveBasePackage(String basePackage) {
return ClassUtils.convertClassNameToResourcePath(basePackage);
}
}