Skip to content

Commit e01f689

Browse files
committed
forward port #2519
fixes #2531
1 parent e09b3e3 commit e01f689

File tree

9 files changed

+61
-76
lines changed

9 files changed

+61
-76
lines changed

core/src/main/java/dev/morphia/mapping/codec/MorphiaCollectionPropertyCodecProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public <T> Codec<T> get(TypeWithTypeParameters<T> type, PropertyCodecRegistry re
3434
} catch (CodecConfigurationException e) {
3535
if (valueType.getType().equals(Object.class)) {
3636
try {
37-
return (Codec<T>) registry.get(TypeData.builder(Collection.class).build());
37+
return (Codec<T>) registry.get(TypeData.get(Collection.class));
3838
} catch (CodecConfigurationException e1) {
3939
// Ignore and return original exception
4040
}

core/src/main/java/dev/morphia/mapping/codec/MorphiaMapPropertyCodecProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public <T> Codec<T> get(TypeWithTypeParameters<T> type, PropertyCodecRegistry re
4040
} catch (CodecConfigurationException e) {
4141
if (valueType.getType().equals(Object.class)) {
4242
try {
43-
return (Codec<T>) registry.get(TypeData.builder(Map.class).build());
43+
return (Codec<T>) registry.get(TypeData.get(Map.class));
4444
} catch (CodecConfigurationException e1) {
4545
// Ignore and return original exception
4646
}

core/src/main/java/dev/morphia/mapping/codec/MorphiaPropertyCodecProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,6 @@ public abstract class MorphiaPropertyCodecProvider implements PropertyCodecProvi
1919
protected TypeWithTypeParameters<?> getType(List<? extends TypeWithTypeParameters<?>> typeParameters, int position) {
2020
return typeParameters.size() > position
2121
? typeParameters.get(position)
22-
: TypeData.builder(Object.class).build();
22+
: TypeData.get(Object.class);
2323
}
2424
}

core/src/main/java/dev/morphia/mapping/codec/pojo/EntityModelBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ public TypeData<?> getTypeData(Class<?> type, TypeData<?> suggested, Type generi
222222
if (map != null) {
223223
Type mapped = map.get(((TypeVariable<?>) genericType).getName());
224224
if (mapped != null) {
225-
suggested = TypeData.newInstance(mapped);
225+
suggested = TypeData.get(mapped);
226226
}
227227
}
228228
}

core/src/main/java/dev/morphia/mapping/codec/pojo/TypeData.java

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,26 @@
3535
public class TypeData<T> implements TypeWithTypeParameters<T> {
3636

3737
private final Class<T> type;
38-
private final List<TypeData<?>> typeParameters;
38+
private final List<TypeData<?>> typeParameters = new ArrayList<>();
3939
private boolean array;
4040

41+
/**
42+
* Creates a new TypeData with the concrete type and type parameters around it.
43+
* <p>
44+
* e.g., List&lt;Address&gt; would be
45+
*
46+
* <pre>
47+
* <code>
48+
* new TypeData(Address.class, TypeData.builder(List.class).build())
49+
* </code>
50+
* </pre>
51+
*
52+
* @param type the type
53+
*/
54+
public TypeData(Class<T> type) {
55+
this.type = type;
56+
}
57+
4158
/**
4259
* Creates a new TypeData with the concrete type and type parameters around it.
4360
* <p>
@@ -54,7 +71,7 @@ public class TypeData<T> implements TypeWithTypeParameters<T> {
5471
*/
5572
public TypeData(Class<T> type, List<TypeData<?>> typeParameters) {
5673
this.type = type;
57-
this.typeParameters = typeParameters;
74+
this.typeParameters.addAll(typeParameters);
5875
}
5976

6077
/**
@@ -69,13 +86,13 @@ public static <T> Builder<T> builder(Class<T> type) {
6986
}
7087

7188
@SuppressWarnings({ "unchecked", "rawtypes" })
72-
private static TypeData<?> getTypeData(Type type) {
89+
public static TypeData<?> get(Type type) {
7390
if (type instanceof ParameterizedType) {
7491
ParameterizedType pType = (ParameterizedType) type;
7592
TypeParameters parameters = TypeParameters.of(pType);
7693
Builder paramBuilder = TypeData.builder((Class) pType.getRawType());
7794
for (Type argType : parameters) {
78-
paramBuilder.addTypeParameter(getTypeData(argType));
95+
paramBuilder.addTypeParameter(get(argType));
7996
}
8097
return paramBuilder.build();
8198
} else if (type instanceof WildcardType) {
@@ -84,18 +101,18 @@ private static TypeData<?> getTypeData(Type type) {
84101
Type[] bounds = upperBounds != null
85102
? upperBounds
86103
: wildcardType.getLowerBounds();
87-
return WildCardTypeData.builder(getTypeData(bounds[0]), upperBounds != null).build();
104+
return new WildCardTypeData(get(bounds[0]), upperBounds != null);
88105
} else if (type instanceof TypeVariable) {
89106
return TypeData.builder(Object.class).build();
90107
} else if (type instanceof Class) {
91-
Builder builder = TypeData.builder((Class) type);
108+
var typeData = new TypeData((Class) type);
92109
for (Type argType : TypeParameters.of(type)) {
93-
builder.addTypeParameter(getTypeData(argType));
110+
typeData.typeParameters.add(argType.equals(type) ? type : get(argType));
94111
}
95-
return builder.build();
112+
return typeData;
96113
} else if (type instanceof GenericArrayType) {
97114
GenericArrayType arrayType = (GenericArrayType) type;
98-
TypeData<?> typeData = getTypeData(arrayType.getGenericComponentType());
115+
TypeData<?> typeData = get(arrayType.getGenericComponentType());
99116
typeData.setArray(true);
100117
return typeData;
101118
}
@@ -211,8 +228,8 @@ private static String nestedTypeParameters(List<TypeData<?>> typeParameters) {
211228
* @param field the field to analyze
212229
* @return the new TypeData information
213230
*/
214-
public static TypeData<?> newInstance(Field field) {
215-
return newInstance(field.getGenericType());
231+
public static TypeData<?> get(Field field) {
232+
return get(field.getGenericType());
216233
}
217234

218235
/**
@@ -221,7 +238,7 @@ public static TypeData<?> newInstance(Field field) {
221238
* @param method the method to analyze
222239
* @return the new TypeData information
223240
*/
224-
public static TypeData<?> newInstance(Method method) {
241+
public static TypeData<?> get(Method method) {
225242
return newInstance(method.getGenericReturnType());
226243
}
227244

@@ -243,7 +260,7 @@ public static <T> TypeData<T> newInstance(Type genericType) {
243260
* }
244261
* return builder.build();
245262
*/
246-
return (TypeData<T>) getTypeData(genericType);
263+
return (TypeData<T>) get(genericType);
247264
}
248265

249266
/**

core/src/main/java/dev/morphia/mapping/codec/pojo/WildCardTypeData.java

Lines changed: 0 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,6 @@ public class WildCardTypeData<T> extends TypeData<T> {
2121
this.upperBound = upperBound;
2222
}
2323

24-
/**
25-
* Creates a builder
26-
*
27-
* @param bound
28-
* @param upperBound true if the type parameters represent an upper bound
29-
* @return the new builder
30-
*/
31-
public static Builder builder(TypeData<?> bound, boolean upperBound) {
32-
return new Builder(bound, upperBound);
33-
}
34-
3524
@Override
3625
public int hashCode() {
3726
return Objects.hash(super.hashCode(), upperBound);
@@ -52,52 +41,8 @@ public boolean equals(Object o) {
5241
return upperBound == that.upperBound;
5342
}
5443

55-
/**
56-
* @return true if the type parameters represent an upper bound
57-
*/
58-
public boolean isUpperBound() {
59-
return upperBound;
60-
}
61-
6244
@Override
6345
public String toString() {
64-
/*
65-
* String value = type.getSimpleName();
66-
* if (!typeParameters.isEmpty()) {
67-
* StringJoiner joiner = new StringJoiner(", ", "<", ">");
68-
* typeParameters.forEach(t -> {
69-
* joiner.add(t.toString());
70-
* });
71-
* value += joiner;
72-
* }
73-
*/
74-
7546
return (upperBound ? "? extends " : "? super ") + super.toString();
7647
}
77-
78-
/**
79-
* A builder for WildCardTypeData
80-
*/
81-
public static class Builder {
82-
private final boolean upperBound;
83-
private final TypeData typeData;
84-
85-
/**
86-
* Creates a builder
87-
*
88-
* @param bound
89-
* @param upperBound true if the type parameters represent an upper bound
90-
*/
91-
public Builder(TypeData bound, boolean upperBound) {
92-
this.typeData = bound;
93-
this.upperBound = upperBound;
94-
}
95-
96-
/**
97-
* @return the new WildCardTypeData
98-
*/
99-
public WildCardTypeData build() {
100-
return new WildCardTypeData(typeData, upperBound);
101-
}
102-
}
10348
}

core/src/main/java/dev/morphia/mapping/conventions/FieldDiscovery.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public void apply(Mapper mapper, EntityModelBuilder builder) {
2929
for (Class<?> type : list) {
3030
for (Field field : type.getDeclaredFields()) {
3131

32-
TypeData<?> typeData = builder.getTypeData(type, TypeData.newInstance(field), field.getGenericType());
32+
TypeData<?> typeData = builder.getTypeData(type, TypeData.get(field), field.getGenericType());
3333
try {
3434
builder.addProperty()
3535
.name(field.getName())

core/src/main/java/dev/morphia/mapping/conventions/MethodDiscovery.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ private List<Methods> processMethods(Class<?> type) {
6262

6363
private void addProperties(EntityModelBuilder builder, Set<Methods> properties) {
6464
for (Methods methods : properties) {
65-
TypeData<?> typeData = entityModelBuilder.getTypeData(methods.type, TypeData.newInstance(methods.getter),
65+
TypeData<?> typeData = entityModelBuilder.getTypeData(methods.type, TypeData.get(methods.getter),
6666
methods.getter.getGenericReturnType());
6767

6868
entityModelBuilder.addProperty()

core/src/test/java/dev/morphia/test/mapping/codec/pojo/TypeDataTest.java

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import java.util.List;
77
import java.util.Locale;
88

9+
import dev.morphia.annotations.Entity;
10+
import dev.morphia.annotations.Id;
911
import dev.morphia.mapping.codec.pojo.TypeData;
1012
import dev.morphia.test.TestBase;
1113
import dev.morphia.test.mapping.codec.pojo.generics.FullHashMap;
@@ -22,7 +24,7 @@
2224
public class TypeDataTest extends TestBase {
2325
@Test
2426
public void testWildcards() throws NoSuchFieldException {
25-
TypeData<?> typeData = TypeData.newInstance(WildCard.class.getDeclaredField("listOfLists"));
27+
TypeData<?> typeData = TypeData.get(WildCard.class.getDeclaredField("listOfLists"));
2628

2729
assertEquals(typeData.getType(), List.class);
2830
List<TypeData<?>> typeParameters = typeData.getTypeParameters();
@@ -64,10 +66,16 @@ public void testSubtypes() {
6466
});
6567
}
6668

69+
@Test
70+
public void testRecursiveTypes() {
71+
TypeData.get(MyEntity.class);
72+
TypeData.get(MyEmbeddedEntity.class);
73+
}
74+
6775
private static void typeData(Class<?> owner, String fieldName, Class<?> fieldType, Class<?>... parameterTypes)
6876
throws NoSuchFieldException {
6977
Field field = owner.getDeclaredField(fieldName);
70-
TypeData<?> typeData = TypeData.newInstance(field);
78+
TypeData<?> typeData = TypeData.get(field);
7179
assertEquals(typeData.getType(), fieldType);
7280
List<TypeData<?>> typeParameters = typeData.getTypeParameters();
7381
assertEquals(typeParameters.size(), parameterTypes.length);
@@ -79,4 +87,19 @@ private static void typeData(Class<?> owner, String fieldName, Class<?> fieldTyp
7987
private static class WildCard {
8088
private List<? extends List<String>> listOfLists;
8189
}
90+
91+
private static class MongoEntity<T> {
92+
}
93+
94+
@Entity
95+
private static class MyEmbeddedEntity extends MongoEntity<MyEmbeddedEntity> {
96+
}
97+
98+
@Entity
99+
private static class MyEntity {
100+
@Id
101+
private String id;
102+
private String address;
103+
List<MyEmbeddedEntity> embeddedEntities;
104+
}
82105
}

0 commit comments

Comments
 (0)