Skip to content

Commit abe5ddd

Browse files
Objects serialized as references using IDs (#298)
- handling `JsonIdentityReference` annotation also on properties
1 parent 22b4fa6 commit abe5ddd

File tree

2 files changed

+32
-12
lines changed

2 files changed

+32
-12
lines changed

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/parser/Jackson2Parser.java

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,9 @@ private BeanModel parseBean(SourceType<Class<?>> sourceClass) {
137137
propertyType = Utils.replaceRawClassInType(propertyType, Map.class);
138138
}
139139
}
140-
140+
141141
// @JsonIdentityInfo and @JsonIdentityReference
142-
propertyType = processIdentity(propertyType);
142+
propertyType = processIdentity(propertyType, beanPropertyWriter);
143143

144144
if (!isAnnotatedPropertyIncluded(beanPropertyWriter::getAnnotation, sourceClass.type.getName() + "." + beanPropertyWriter.getName())) {
145145
continue;
@@ -201,29 +201,31 @@ private BeanModel parseBean(SourceType<Class<?>> sourceClass) {
201201
return new BeanModel(sourceClass.type, superclass, taggedUnionClasses, discriminantProperty, discriminantLiteral, interfaces, properties, null);
202202
}
203203

204-
private Type processIdentity(Type propertyType) {
204+
private Type processIdentity(Type propertyType, BeanPropertyWriter propertyWriter) {
205205
final Class<?> cls = Utils.getRawClassOrNull(propertyType);
206206
if (cls != null) {
207207
final JsonIdentityInfo identityInfo = cls.getAnnotation(JsonIdentityInfo.class);
208208
if (identityInfo == null) {
209209
return propertyType;
210210
}
211-
final JsonIdentityReference identityReference = cls.getAnnotation(JsonIdentityReference.class);
211+
final JsonIdentityReference identityReferenceC = cls.getAnnotation(JsonIdentityReference.class);
212+
final JsonIdentityReference identityReferenceP = propertyWriter.getAnnotation(JsonIdentityReference.class);
213+
final JsonIdentityReference identityReference = identityReferenceP != null ? identityReferenceP : identityReferenceC;
212214
final boolean alwaysAsId = identityReference != null && identityReference.alwaysAsId();
213215

214216
final Type idType;
215217
if (identityInfo.generator() == ObjectIdGenerators.None.class) {
216218
return propertyType;
217219
} else if (identityInfo.generator() == ObjectIdGenerators.PropertyGenerator.class) {
218220
final BeanPropertyWriter[] properties = getBeanHelper(cls).getProperties();
219-
final Optional<BeanPropertyWriter> property = Stream.of(properties)
221+
final Optional<BeanPropertyWriter> idProperty = Stream.of(properties)
220222
.filter(p -> p.getName().equals(identityInfo.property()))
221223
.findFirst();
222-
if (property.isPresent()) {
223-
final BeanPropertyWriter beanPropertyWriter = property.get();
224-
final Member propertyMember = beanPropertyWriter.getMember().getMember();
225-
checkMember(propertyMember, beanPropertyWriter.getName(), cls);
226-
idType = getGenericType(propertyMember);
224+
if (idProperty.isPresent()) {
225+
final BeanPropertyWriter idPropertyWriter = idProperty.get();
226+
final Member idPropertyMember = idPropertyWriter.getMember().getMember();
227+
checkMember(idPropertyMember, idPropertyWriter.getName(), cls);
228+
idType = getGenericType(idPropertyMember);
227229
} else {
228230
return propertyType;
229231
}

typescript-generator-core/src/test/java/cz/habarta/typescript/generator/ObjectAsIdTest.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,16 @@ public void testJackson() throws JsonProcessingException {
2020
final TestObjectA testObjectA = new TestObjectA();
2121
final TestObjectB testObjectB = new TestObjectB();
2222
final TestObjectC<String> testObjectC = new TestObjectC<>("valueC");
23+
final TestObjectD testObjectD = new TestObjectD();
2324
final Wrapper wrapper = new Wrapper();
2425
wrapper.testObjectA1 = testObjectA;
2526
wrapper.testObjectA2 = testObjectA;
2627
wrapper.testObjectB1 = testObjectB;
2728
wrapper.testObjectB2 = testObjectB;
2829
wrapper.testObjectC1 = testObjectC;
2930
wrapper.testObjectC2 = testObjectC;
31+
wrapper.testObjectD1 = testObjectD;
32+
wrapper.testObjectD2 = testObjectD;
3033
final ObjectMapper objectMapper = Utils.getObjectMapper();
3134
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
3235
final String json = objectMapper.writeValueAsString(wrapper);
@@ -35,7 +38,9 @@ public void testJackson() throws JsonProcessingException {
3538
Assert.assertTrue(json.contains("\"testObjectB1\": {"));
3639
Assert.assertTrue(json.contains("\"testObjectB2\": \"id2\""));
3740
Assert.assertTrue(json.contains("\"testObjectC1\": {"));
38-
Assert.assertTrue(json.contains("\"testObjectC2\": \"id2\""));
41+
Assert.assertTrue(json.contains("\"testObjectC2\": \"id3\""));
42+
Assert.assertTrue(json.contains("\"testObjectD1\": \"id4\""));
43+
Assert.assertTrue(json.contains("\"testObjectD2\": \"id4\""));
3944
}
4045

4146
@Test
@@ -45,9 +50,11 @@ public void test() {
4550
Assert.assertTrue(output.contains("testObjectA1: string"));
4651
Assert.assertTrue(output.contains("testObjectB1: TestObjectB | string"));
4752
Assert.assertTrue(output.contains("testObjectC1: TestObjectC<string> | string"));
53+
Assert.assertTrue(output.contains("testObjectD1: string"));
4854
Assert.assertTrue(!output.contains("interface TestObjectA"));
4955
Assert.assertTrue(output.contains("interface TestObjectB"));
5056
Assert.assertTrue(output.contains("interface TestObjectC<T>"));
57+
Assert.assertTrue(!output.contains("interface TestObjectD"));
5158
}
5259

5360
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "@@@id")
@@ -73,7 +80,7 @@ private static class TestObjectB {
7380
private static class TestObjectC<T> {
7481

7582
@JsonProperty("@@@id")
76-
public String myIdentification = "id2";
83+
public String myIdentification = "id3";
7784

7885
public T myProperty;
7986

@@ -82,13 +89,24 @@ public TestObjectC(T myProperty) {
8289
}
8390
}
8491

92+
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "@@@id")
93+
private static class TestObjectD {
94+
95+
@JsonProperty("@@@id")
96+
public String myIdentification = "id4";
97+
98+
public String myProperty = "valueD";
99+
}
100+
85101
private static class Wrapper {
86102
public TestObjectA testObjectA1;
87103
public TestObjectA testObjectA2;
88104
public TestObjectB testObjectB1;
89105
public TestObjectB testObjectB2;
90106
public TestObjectC<String> testObjectC1;
91107
public TestObjectC<String> testObjectC2;
108+
public @JsonIdentityReference(alwaysAsId = true) TestObjectD testObjectD1;
109+
public @JsonIdentityReference(alwaysAsId = true) TestObjectD testObjectD2;
92110
}
93111

94112
}

0 commit comments

Comments
 (0)