Skip to content

Commit

Permalink
Correctly get Collection generic parameter type
Browse files Browse the repository at this point in the history
  • Loading branch information
hevav committed Aug 30, 2023
1 parent 8e0c2a5 commit 6a7ece2
Showing 1 changed file with 67 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
import java.io.BufferedReader;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
Expand Down Expand Up @@ -180,6 +182,65 @@ public void readSerializableObject(@Nullable Field owner, Object holder, Class<?
}
}

private int getParameterIndex(TypeVariable<?>[] variables, TypeVariable<?> expected) {
for (int i = 0; i < variables.length; ++i) {
if (variables[i].getName().equals(expected.getName())) {
return i;
}
}

return -1;
}

private Type getCollectionTypeFromSuperclass(Type type, Type superclass) {
Type superclassType = this.getCollectionType(superclass);
if (superclassType instanceof TypeVariable<?> typeVariable && type instanceof ParameterizedType parameterizedType) {
Class<?> rawSuperclass = (Class<?>) parameterizedType.getRawType();
int index = this.getParameterIndex(rawSuperclass.getTypeParameters(), typeVariable);
if (index != -1) {
return parameterizedType.getActualTypeArguments()[index];
}
}

return superclassType;
}

private Type getCollectionType(Type type) {
if (type == null) {
return null;
}

Class<?> clazz = null;

if (type instanceof ParameterizedType parameterizedType) {
clazz = (Class<?>) parameterizedType.getRawType();
if (clazz.equals(Collection.class)) {
return parameterizedType.getActualTypeArguments()[0];
}
}

if (type instanceof Class<?> typeClazz) {
clazz = typeClazz;
}

if (clazz != null) {
Type genericSuperclass = clazz.getGenericSuperclass();
Type superclassType = this.getCollectionTypeFromSuperclass(type, genericSuperclass);
if (superclassType != null) {
return superclassType;
}

for (Type genericInterface : clazz.getGenericInterfaces()) {
Type genericInterfaceType = this.getCollectionTypeFromSuperclass(type, genericInterface);
if (genericInterfaceType != null) {
return genericInterfaceType;
}
}
}

return null;
}

private void updatePlaceholders(Object holder, Field node) throws ReflectiveOperationException {
RegisterPlaceholders placeholders = node.getAnnotation(RegisterPlaceholders.class);
if (placeholders == null) {
Expand All @@ -188,15 +249,19 @@ private void updatePlaceholders(Object holder, Field node) throws ReflectiveOper

if (placeholders != null) {
PlaceholderReplacer<?, ?> replacer = null;
Object value = node.get(holder);
if (placeholders.replacer() == DefaultPlaceholderReplacer.class) {
replacer = this.config.getRegisteredReplacer(node.getType());
if (value instanceof Collection<?>) {
replacer = this.config.getRegisteredReplacer((Class<?>) this.getCollectionType(node.getGenericType()));
} else {
replacer = this.config.getRegisteredReplacer(node.getType());
}
}

if (replacer == null) {
replacer = this.config.getAndCacheReplacer(placeholders.replacer());
}

Object value = node.get(holder);
if (this.config.isRegisterPlaceholdersForCollectionEntries() && value instanceof Collection<?> collection) {
for (Object entry : collection) {
Placeholders.addPlaceholders(entry, replacer, placeholders.wrapWithBraces(), placeholders.value());
Expand Down

0 comments on commit 6a7ece2

Please sign in to comment.