Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.moon.core.beans.BeanInfoUtil Maven / Gradle / Ivy
package com.moon.core.beans;
import com.moon.core.lang.ThrowUtil;
import com.moon.core.lang.ref.WeakLocation;
import com.moon.core.lang.reflect.FieldUtil;
import com.moon.core.util.IteratorUtil;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;
import static com.moon.core.lang.ThrowUtil.noInstanceError;
/**
* 在 java 规范中,一个字段至少有 getter 或 setter 方法中的一个才会被认为是这个类的属性
* 同时,如果一个类如果没有某一字段,但却有 setter 或 getter 方法中的一个也会被认为是一个属性
* 以上同时适用于本类和所有父类
*
* @author ZhangDongMin
* @see FieldDescriptor
*/
public abstract class BeanInfoUtil {
private BeanInfoUtil() { noInstanceError(); }
private final static WeakLocation WEAK = WeakLocation.ofManaged();
/**
* 获取标准 setter 方法
*
* @param field 待获取字段
*
* @return setter 方法或抛出异常
*
* @see NoSuchMethodException 找不到 setter 方法(被{@link IllegalArgumentException})包裹
* @see IllegalArgumentException 找不到 setter 方法
*/
public static Method getSetterMethod(Field field) {
return (Method) WEAK
.getOrWithElse(field, TypeEnum.SETTER, () -> getSetterMethod(field.getDeclaringClass(), field.getName()));
}
/**
* 获取标准 getter 方法
*
* @param field 待获取字段
*
* @return getter 方法或抛出异常
*
* @see NoSuchMethodException 找不到 getter 方法(被{@link IllegalArgumentException})包裹
* @see IllegalArgumentException 找不到 getter 方法
*/
public static Method getGetterMethod(Field field) {
return (Method) WEAK
.getOrWithElse(field, TypeEnum.GETTER, () -> getGetterMethod(field.getDeclaringClass(), field.getName()));
}
/**
* 获取标准 setter 方法
*
* @param clazz 目标类
* @param fieldName 待获取字段名
*
* @return setter 方法或抛出异常
*
* @see NoSuchMethodException 找不到 setter 方法(被{@link IllegalArgumentException})包裹
* @see IllegalArgumentException 找不到 setter 方法
*/
public static Method getSetterMethod(Class clazz, String fieldName) {
FieldDescriptor descriptor = getFieldDescriptor(clazz, fieldName);
if (descriptor.isSetterMethodPresent()) {
return descriptor.getSetterMethod();
}
return ThrowUtil
.runtime(new NoSuchMethodException("Not exist setter in class: " + clazz + " of field: " + fieldName));
}
/**
* 获取标准 getter 方法
*
* @param clazz 目标类
* @param fieldName 待获取字段名
*
* @return getter 方法或抛出异常
*
* @see NoSuchMethodException 找不到 getter 方法(被{@link IllegalArgumentException})包裹
* @see IllegalArgumentException 找不到 getter 方法
*/
public static Method getGetterMethod(Class clazz, String fieldName) {
FieldDescriptor descriptor = getFieldDescriptor(clazz, fieldName);
if (descriptor.isGetterMethodPresent()) {
return descriptor.getGetterMethod();
}
return ThrowUtil.runtime(
new NoSuchMethodException("Not exist getter for class: " + clazz + " of field namespace: " + fieldName));
}
/**
* 返回指定字段 getter 执行器
* 执行器与 getter 方法的区别是,getter 是方法,
* 而执行器是在没有 getter 方法的时候直接对字段获取值
*
* @param field 待获取字段
*
* @return getter 执行器
*/
public static FieldExecutor getGetterExecutor(Field field) {
return (FieldExecutor) WEAK.getOrWithElse(field, TypeEnum.GET_EXECUTOR,
() -> getGetterExecutor(field.getDeclaringClass(), field.getName()));
}
/**
* 返回指定字段 setter 执行器
* 执行器与 setter 方法的区别是,setter 是方法,
* 而执行器是在没有 setter 方法的时候直接对字段设置值
*
* @param field 待获取字段
*
* @return setter 执行器
*
* @see IllegalArgumentException 当 field 被 final 修饰,且没有对应的 setter 方法就会抛出异常
*/
public static FieldExecutor getSetterExecutor(Field field) {
return (FieldExecutor) WEAK.getOrWithElse(field, TypeEnum.SET_EXECUTOR,
() -> getSetterExecutor(field.getDeclaringClass(), field.getName()));
}
/**
* 返回指定字段 getter 执行器
* 执行器与 getter 方法的区别是,getter 是方法,
* 而执行器是在没有 getter 方法的时候直接对字段获取值
*
* @param clazz 目标类
* @param propertyName 待获取字段名
*
* @return getter 执行器
*
* @see IllegalArgumentException 当 clazz 不存在字段属性时
*/
public static FieldExecutor getGetterExecutor(Class clazz, String propertyName) {
return getFieldDescriptor(clazz, propertyName).getGetterExecutor();
}
/**
* 返回指定字段 setter 执行器
* 执行器与 setter 方法的区别是,setter 是方法,
* 而执行器是在没有 setter 方法的时候直接对字段设置值
*
* @param clazz 目标类
* @param propertyName 待获取字段名
*
* @return setter 执行器
*
* @see IllegalArgumentException 当 clazz 不存在对应属性,或对应字段被 final 修饰时,抛出异常
*/
public static FieldExecutor getSetterExecutor(Class clazz, String propertyName) {
return getFieldDescriptor(clazz, propertyName).getSetterExecutor();
}
public static void ifSetterExecutorPresent(Class clazz, String propertyName, Consumer c) {
try {
getFieldDescriptor(clazz, propertyName).ifSetterPresent(c);
} catch (IllegalArgumentException e) {
// ignore
}
}
public static void ifGetterExecutorPresent(Class clazz, String propertyName, Consumer c) {
try {
getFieldDescriptor(clazz, propertyName).ifGetterPresent(c);
} catch (IllegalArgumentException e) {
// ignore
}
}
/**
* 返回属性描述信息
*
* @param clazz 目标类
*
* @return 类属性描述器集合
*/
public static Map getPropertyDescriptorsMap(Class clazz) {
return (Map) WEAK.getOrWithElse(clazz, TypeEnum.ALL_DESC_MAP, () -> {
Map ret = new HashMap<>();
IteratorUtil.forEach(getPropertyDescriptors(clazz), desc -> ret.put(desc.getName(), desc));
return ret;
});
}
/**
* 返回指定类的所有字段描述信息
* 这儿取出的字段可能包含没有 getter / setter 方法的字段信息,也可能不包含
*
* @param clazz 目标类
*
* @return 类字段描述器集合
*/
public static Map getFieldDescriptorsMap(Class clazz) {
return (Map) WEAK
.getOrWithElse(Objects.requireNonNull(clazz), TypeEnum.ALL_FIELD_MAP, () -> {
Map ret = new HashMap<>();
IteratorUtil.forEach(getPropertyDescriptors(clazz), desc -> {
String name = desc.getName();
if (!isNameOfClass(name)) {
ret.put(name, FieldDescriptor.of(clazz, name, desc));
}
});
return ret;
});
}
/**
* 返回所有属性描述信息
*
* @param clazz 目标类
*
* @return 属性描述器
*/
public static PropertyDescriptor[] getPropertyDescriptors(Class clazz) {
return (PropertyDescriptor[]) WEAK.getOrWithElse(clazz, TypeEnum.ALL_DESC, () -> {
try {
BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
return beanInfo.getPropertyDescriptors();
} catch (IntrospectionException e) {
return ThrowUtil.runtime(e);
}
});
}
/**
* 返回属性描述信息
*
* @param clazz 目标类
* @param propertyName 目标属性名
*
* @return 目标属性描述器
*
* @see IllegalArgumentException 当 clazz 不存在能访问到的对应名称属性时
*/
public static PropertyDescriptor getPropertyDescriptor(Class clazz, String propertyName) {
FieldDescriptor descriptor = getFieldDescriptor(clazz, propertyName);
return descriptor == null ? null : descriptor.getProperty();
}
/**
* 获取指定字段的字段描述信息
*
* @param field 目标字段
*
* @return 目标字段描述器
*/
public static FieldDescriptor getFieldDescriptor(Field field) {
return (FieldDescriptor) WEAK.getOrWithElse(field, TypeEnum.DESCRIPTOR,
() -> getFieldDescriptor(field.getDeclaringClass(), field.getName()));
}
/**
* 获取指定 clazz 类中指定字段名描述信息,与 PropertyDescriptor 的区别是,
* PropertyDescriptor 不包含同时没有 getter / setter 方法的字段,
* 而通过 FieldDescriptor 能返回对应字段信息
*
* @param clazz 目标类
* @param propertyName 目标属性
*
* @return 目标字段描述器
*
* @see IllegalArgumentException 当 clazz 不存在能访问到的对应名称属性时
*/
public static FieldDescriptor getFieldDescriptor(Class clazz, String propertyName) {
String name = Objects.requireNonNull(propertyName);
return (FieldDescriptor) WEAK.getOrWithElse(clazz, name, () -> {
Map descriptorMap = getFieldDescriptorsMap(clazz);
FieldDescriptor descriptor = descriptorMap.get(name);
if (descriptor == null) {
Field field = FieldUtil.getAccessibleField(clazz, name);
descriptor = FieldDescriptor.of(clazz, name, field);
descriptorMap.put(name, descriptor);
}
return descriptor;
});
}
/**
* 字段名是否是 class,由于每个类都有默认的 getClass 方法,
* 故每个类都有一个名为 class 的属性,在这里排除这个字段
*
* @param name 字段名
*
* @return 是否是 class 字段(对应{@link #getClass()})方法
*/
static boolean isNameOfClass(String name) {
return "class".equals(name);
}
enum TypeEnum {
ALL_DESC,
ALL_DESC_MAP,
ALL_FIELD_MAP,
SETTER,
GETTER,
SET_EXECUTOR,
GET_EXECUTOR,
DESCRIPTOR
}
}