com.gitee.l0km.casban.CasbanScanners Maven / Gradle / Ivy
package com.gitee.l0km.casban;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Predicates.and;
import static com.google.common.base.Predicates.notNull;
import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Member;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import com.gitee.l0km.aocache.annotations.AoWeakCacheable;
import com.gitee.l0km.aocache.guava.common.base.Strings;
import com.gitee.l0km.casban.exception.PackageScanException;
import com.gitee.l0km.common.spring.core.annotation.MergedAnnotation;
import com.gitee.l0km.common.spring.core.annotation.RepeatableContainers;
import com.gitee.l0km.common.spring.core.annotation.TypeMappedAnnotations;
import com.gitee.l0km.common.spring.core.annotation.MergedAnnotations.SearchStrategy;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Supplier;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Sets;
/**
* @author guyadong
* @since 1.1.0
*/
public class CasbanScanners {
@AoWeakCacheable
public static LinkedHashSet> findClasses(Iterable> classes,
Supplier finisher, Iterable>> filters){
checkNotNull(classes,"classes is null");
LinkedHashSet>> _filters = Sets.newLinkedHashSet(
Arrays.asList(Predicates.>notNull(),
CommonPredicates.publicClassFilter()));
if(filters != null) {
FluentIterable.from(filters).filter(notNull()).copyInto(_filters);
}
LinkedHashSet> filtered = FluentIterable.from(classes)
.filter(and(_filters))
.copyInto(new LinkedHashSet>());
if(null == finisher) {
finisher = CountLimitStrategy.ANY;
}
return finisher.get().checkSize(filtered);
}
@SafeVarargs
public static LinkedHashSet> findClasses(Iterable> classes,
Supplier finisher, Predicate>... filters){
return findClasses(classes,finisher,null == filters ? null : FluentIterable.from(filters));
}
@AoWeakCacheable
public static LinkedHashSet findMembersOfClass(Class> clazz,
Iterable> filters){
checkNotNull(clazz,"classes is null");
LinkedHashSet> _filters =
Sets.newLinkedHashSet(Arrays.asList(Predicates.notNull()));
if(filters != null) {
FluentIterable.from(filters).filter(notNull()).copyInto(_filters);
}
Predicate _and = and(_filters);
LinkedHashSet result = new LinkedHashSet<>();
try {
FluentIterable.from(clazz.getFields()).filter(_and).copyInto(result);
FluentIterable.from(clazz.getMethods()).filter(_and).copyInto(result);
} catch (NoClassDefFoundError e) {
/** 可能会遇到找不到方法或字段中涉及的类的问题,比如某些依赖以provided方式提供 */
// DO NOTHING
throw e;
}
return result;
}
@SafeVarargs
public static LinkedHashSet findMembersOfClass(Class> clazz,
Predicate... filters){
return findMembersOfClass(clazz,null == filters ? null: Arrays.asList(filters));
}
public static LinkedHashSet findMembersOfClass(Class> clazz,
Function as,
Iterable> filters){
return FluentIterable.from(findMembersOfClass(clazz,filters))
.transform(checkNotNull(as,"as is null"))
.filter(Predicates.notNull())
.copyInto(new LinkedHashSet());
}
@SafeVarargs
public static LinkedHashSet findMembersOfClass(Class> clazz,
Function as,
Predicate... filters){
return findMembersOfClass(clazz,as,null == filters ? null: Arrays.asList(filters));
}
public static Member findMember(Class> clazz,
boolean onlyOne,
Iterable> filters){
LinkedHashSet members = findMembersOfClass(clazz,filters);
return fetchClassOrnull(members,onlyOne,"member");
}
@SafeVarargs
public static Member findMember(Class> clazz,
boolean onlyOne,
Predicate... filters){
return findMember(clazz, onlyOne, null == filters ? null: Arrays.asList(filters));
}
public static A findAccessibleObject(Class> clazz,
boolean onlyOne,
Function as,
Iterable> filters){
LinkedHashSet members = findMembersOfClass(clazz,as,filters);
return fetchClassOrnull(members,onlyOne,"member");
}
@SafeVarargs
public static A findAccessibleObject(Class> clazz,
boolean onlyOne,
Function as,
Predicate... filters){
return findAccessibleObject(clazz,onlyOne,as,null == filters ? null: Arrays.asList(filters));
}
public static Member findMember(Iterable input,
boolean onlyOne, Iterable> memberFilters){
LinkedHashSet members = findMembers(input,
onlyOne? CountLimitStrategy.ONLY_ONE:CountLimitStrategy.MOST_ONE,
memberFilters);
return members.isEmpty() ? null : members.iterator().next();
}
public static LinkedHashSet findMembers(Class> clazz,
LinkedHashSet result,
Iterable> filters){
result.addAll(findMembersOfClass(clazz,filters));
return result;
}
@SuppressWarnings("unchecked")
public static LinkedHashSet findMembers(Class> clazz,
LinkedHashSet result,
Predicate... filters){
return findMembers(clazz,result,null == filters ? null : FluentIterable.from(filters));
}
public static LinkedHashSet findMembers(Iterable> classes,
Supplier finisher,
Iterable>> classFilters,
Iterable> memberFilters){
LinkedHashSet> filteredClasses = findClasses(classes,CountLimitStrategy.ANY,classFilters);
LinkedHashSet result = new LinkedHashSet();
for(Class> clazz:filteredClasses) {
findMembers(clazz,result,memberFilters);
}
if(null == finisher) {
finisher = CountLimitStrategy.ANY;
}
return finisher.get().checkSize(result);
}
public static Member findMember(Iterable> classes,
boolean onlyOne,
Iterable>> classFilters, Iterable> memberFilters){
LinkedHashSet members = findMembers(classes,
onlyOne? CountLimitStrategy.ONLY_ONE:CountLimitStrategy.MOST_ONE,
classFilters,memberFilters);
return members.isEmpty() ? null : members.iterator().next();
}
public static LinkedHashSet findMembers(Iterable members,
Supplier finisher,
Iterable> filters){
checkNotNull(members,"members is null");
LinkedHashSet> _filters =
Sets.newLinkedHashSet(Arrays.asList(Predicates.notNull()));
if(filters != null) {
FluentIterable.from(filters).filter(notNull()).copyInto(_filters);
}
Predicate _and = and(_filters);
try {
LinkedHashSet filtered = FluentIterable.from(members).filter(_and).copyInto(new LinkedHashSet());
if(null == finisher) {
finisher = CountLimitStrategy.ANY;
}
return finisher.get().checkSize(filtered);
} catch (NoClassDefFoundError e) {
/** 可能会遇到找不到方法或字段中涉及的类的问题,比如某些依赖以provided方式提供 */
// DO NOTHING
throw e;
}
}
public static T fetchClassOrnull(Set classes,boolean onlyOne, String elementName){
switch(classes.size()) {
case 0:
if(onlyOne) {
throw new PackageScanException(
"NOT FOUND OR FOUND matched "+String.valueOf(elementName));
}
return null;
case 1:
return classes.iterator().next();
default:
throw new PackageScanException(
String.format("FOUND %s matched %s:%s",
classes.size(),
String.valueOf(elementName),
CommonFunctions.joinFun().apply(classes)));
}
}
/**
* 获取可重复注解
* 参考 {@link com.gitee.l0km.common.spring.core.annotation.AnnotatedElementUtils#findMergedRepeatableAnnotations(AnnotatedElement, Class)}实现,
* 支持注解为元注解,且定义的该元注解的注解也是可重复注解
* @param
* @param annotatedElement
* @param annotationType
*/
public static Iterable> findMergedRepeatableAnnotations(AnnotatedElement annotatedElement,ClassannotationType){
RepeatableContainers repeatableContainers = RepeatableContainers.standardRepeatables();
return TypeMappedAnnotations.from(annotatedElement, SearchStrategy.TYPE_HIERARCHY, repeatableContainers)
.iterable(annotationType);
}
/**
* [递归]返回{@code annotationType}指定注解的方法(字段)上是否有 {@code targetType}指定的注解,
* 如果没有找到且{@code searchMeta}为{@code true}会递归搜索所有元注解
* 输入参数为{@code null}或空返回{@code false}
* @param annotationType
* @param targetType 注解类名
* @param searchMeta 是否搜索元注解
*/
@AoWeakCacheable
public static boolean withAnnotation(Class extends Annotation> annotationType, String targetType, boolean searchMeta) {
if(null != annotationType && !Strings.isNullOrEmpty(targetType)) {
for(java.lang.reflect.Method method: annotationType.getMethods()) {
if(com.gitee.l0km.common.spring.core.annotation.TypeMappedAnnotations
.from(method).isDirectlyPresent(targetType)) {
return true;
}
}
if(searchMeta) {
for(Iterator>
itor = com.gitee.l0km.common.spring.core.annotation.TypeMappedAnnotations
.from(annotationType).iterator();itor.hasNext();) {
if(withAnnotation(itor.next().getType(), targetType, searchMeta)) {
return true;
}
}
}
}
return false;
}
/**
* [递归]返回{@code annotationType}指定注解的方法(字段)上是否有 {@code targetType}指定的注解,
* 如果没有找到且{@code searchMeta}为{@code true}会递归搜索所有元注解
* 输入参数为{@code null}或空返回{@code false}
* @param annotationType
* @param targetType
* @param searchMeta 是否搜索元注解
*/
public static boolean withAnnotation(Class extends Annotation> annotationType, Class extends Annotation> targetType, boolean searchMeta) {
return withAnnotation(annotationType, null == targetType ? null :targetType.getName(), searchMeta);
}
/**
* 判断注解类型是否使用了casban定义的{@link com.gitee.l0km.common.spring.core.annotation.AliasFor}注解
* @param annotationType
*/
public static boolean withCasbanAliasFor(Class extends Annotation> annotationType) {
return withAnnotation(annotationType,"com.gitee.l0km.common.spring.core.annotation.AliasFor", true);
}
/**
* 判断注解类型是否使用了spring定义的{@link com.gitee.l0km.common.spring.core.annotation.AliasFor}注解
* @param annotationType
*/
public static boolean withSpringAliasFor(Class extends Annotation> annotationType) {
return withAnnotation(annotationType,"org.springframework.core.annotation.AliasFor", true);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy