in java/fury-core/src/main/java/org/apache/fury/type/Descriptor.java [495:564]
static SortedMap<Field, Descriptor> buildBeanedDescriptorsMap(
Class<?> clz, boolean searchParent) {
List<Field> fieldList = new ArrayList<>();
Class<?> clazz = clz;
Map<Tuple2<Class, String>, Method> methodMap = new HashMap<>();
do {
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
int modifiers = field.getModifiers();
// final and non-private field validation left to {@link isBean(clz)}
if (!Modifier.isTransient(modifiers)
&& !Modifier.isStatic(modifiers)
&& !field.isAnnotationPresent(Ignore.class)) {
fieldList.add(field);
}
}
Arrays.stream(clazz.getDeclaredMethods())
.filter(m -> !Modifier.isPrivate(m.getModifiers()))
// if override, use subClass method; getter/setter method won't overload
.forEach(m -> methodMap.put(Tuple2.of(m.getDeclaringClass(), m.getName()), m));
clazz = clazz.getSuperclass();
} while (clazz != null && searchParent);
for (Class<?> anInterface : clz.getInterfaces()) {
Method[] methods = anInterface.getDeclaredMethods();
for (Method method : methods) {
if (method.isDefault()) {
methodMap.put(Tuple2.of(method.getDeclaringClass(), method.getName()), method);
}
}
}
// use TreeMap to sort to fix field order
TreeMap<Field, Descriptor> descriptorMap = new TreeMap<>(fieldComparator);
for (Field field : fieldList) {
Class<?> fieldDeclaringClass = field.getDeclaringClass();
String fieldName = field.getName();
String cap = StringUtils.capitalize(fieldName);
Method getter;
if ("boolean".equalsIgnoreCase(field.getType().getSimpleName())) {
getter = methodMap.get(Tuple2.of(fieldDeclaringClass, "is" + cap));
} else {
getter = methodMap.get(Tuple2.of(fieldDeclaringClass, "get" + cap));
}
if (getter != null) {
if (getter.getParameterCount() != 0
|| !getter
.getGenericReturnType()
.getTypeName()
.equals(field.getGenericType().getTypeName())) {
getter = null;
}
}
Method setter = methodMap.get(Tuple2.of(fieldDeclaringClass, "set" + cap));
if (setter != null) {
if (setter.getParameterCount() != 1
|| !setter
.getGenericParameterTypes()[0]
.getTypeName()
.equals(field.getGenericType().getTypeName())) {
setter = null;
}
}
TypeRef fieldType = TypeRef.of(field.getGenericType());
descriptorMap.put(field, new Descriptor(field, fieldType, getter, setter));
}
// Don't cache descriptors using a static `WeakHashMap<Class<?>, SortedMap<Field, Descriptor>>`,
// otherwise classes can't be gc.
return descriptorMap;
}