Skip to content

Commit 01d50c1

Browse files
authored
handle deep nested generics (#453)
1 parent be10f79 commit 01d50c1

File tree

4 files changed

+76
-17
lines changed

4 files changed

+76
-17
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package org.example.customer.nesting;
2+
3+
import java.util.Map;
4+
5+
import io.avaje.jsonb.Json;
6+
7+
@Json
8+
public record TestMapMap(Map<String, Map<String, Entity>> dims) {
9+
10+
@Json
11+
public record Entity(String name, String value) {}
12+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.example.customer.nesting;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
5+
import java.util.Map;
6+
7+
import org.junit.jupiter.api.Test;
8+
9+
import io.avaje.jsonb.JsonType;
10+
import io.avaje.jsonb.Jsonb;
11+
12+
class NestingGenericTest {
13+
14+
JsonType<TestMapMap> jsonb = Jsonb.instance().type(TestMapMap.class);
15+
16+
@Test
17+
void asd() {
18+
var res = new TestMapMap(Map.of("test", Map.of("123", new TestMapMap.Entity("name", "value"))));
19+
var to = jsonb.toJson(res);
20+
var from = jsonb.fromJson(to);
21+
assertThat(from).isEqualTo(res);
22+
}
23+
}

jsonb-generator/src/main/java/io/avaje/jsonb/generator/GenericType.java

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import java.util.ArrayList;
44
import java.util.List;
55
import java.util.Set;
6-
import static io.avaje.jsonb.generator.APContext.*;
76

87
/**
98
* A type with generic parameters and potentially nested.
@@ -106,12 +105,17 @@ void writeShortType(StringBuilder sb) {
106105

107106
void writeType(String prefix, StringBuilder sb) {
108107
String main = Util.shortName(trimExtends());
109-
sb.append(prefix).append(main).append(".class");
108+
sb.append(prefix);
110109
final int paramCount = params.size();
110+
if (paramCount > 0) {
111+
sb.append("Types.newParameterizedType(");
112+
}
113+
sb.append(main).append(".class");
111114
if (paramCount > 0) {
112115
for (GenericType param : params) {
113-
param.writeType(",", sb);
116+
param.writeType(", ", sb);
114117
}
118+
sb.append(")");
115119
}
116120
}
117121

@@ -137,7 +141,7 @@ private String trimExtends() {
137141
}
138142

139143
String topType() {
140-
return (mainType != null) ? mainType : raw;
144+
return mainType != null ? mainType : raw;
141145
}
142146

143147
void setMainType(String mainType) {
@@ -157,8 +161,8 @@ String asTypeDeclaration() {
157161
if (result != null) return result;
158162
}
159163
StringBuilder sb = new StringBuilder();
160-
writeType("Types.newParameterizedType(", sb);
161-
return sb.append(")").toString();
164+
writeType("", sb);
165+
return sb.toString();
162166
}
163167

164168
private String asTypeBasic() {
@@ -173,17 +177,21 @@ private String asTypeBasic() {
173177
private String asTypeContainer() {
174178
GenericType param = params.get(0);
175179
String containerType = topType();
176-
if ("java.util.List".equals(containerType) || "java.util.ArrayList".equals(containerType)) {
177-
return "Types.listOf(" + Util.shortName(param.topType()) + ".class)";
178-
}
179-
if ("java.util.Set".equals(containerType) || "java.util.LinkedHashSet".equals(containerType)) {
180-
return "Types.setOf(" + Util.shortName(param.topType()) + ".class)";
181-
}
182-
if ("java.util.stream.Stream".equals(containerType)) {
183-
return "Types.streamOf(" + Util.shortName(param.topType()) + ".class)";
184-
}
185-
if ("java.util.Optional".equals(containerType)) {
186-
return "Types.optionalOf(" + Util.shortName(param.topType()) + ".class)";
180+
if (containerType != null) {
181+
switch (containerType) {
182+
case "java.util.List":
183+
case "java.util.ArrayList":
184+
return "Types.listOf(" + Util.shortName(param.topType()) + ".class)";
185+
case "java.util.Set":
186+
case "java.util.LinkedHashSet":
187+
return "Types.setOf(" + Util.shortName(param.topType()) + ".class)";
188+
case "java.util.stream.Stream":
189+
return "Types.streamOf(" + Util.shortName(param.topType()) + ".class)";
190+
case "java.util.Optional":
191+
return "Types.optionalOf(" + Util.shortName(param.topType()) + ".class)";
192+
default:
193+
break;
194+
}
187195
}
188196
return null;
189197
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package io.avaje.jsonb.generator.models.valid.nested;
2+
3+
import java.util.Map;
4+
5+
import io.avaje.jsonb.Json;
6+
7+
@Json
8+
public class TestMapMap {
9+
Map<String, Map<String, Entity>> dims;
10+
11+
@Json
12+
public static class Entity {
13+
String name;
14+
String value;
15+
}
16+
}

0 commit comments

Comments
 (0)