Skip to content

Commit 475c539

Browse files
mbaechlerchibenwa
authored andcommitted
JAMES-2813 demonstrate how to handle nested DTOs with some tests
1 parent 27f2845 commit 475c539

13 files changed

+356
-20
lines changed

json/src/test/java/org/apache/DTOConverterTest.java

+7-4
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.apache.dto.BaseType;
3030
import org.apache.dto.FirstDTO;
3131
import org.apache.dto.FirstDomainObject;
32+
import org.apache.dto.NestedType;
3233
import org.apache.dto.SecondDTO;
3334
import org.apache.dto.SecondDomainObject;
3435
import org.apache.dto.TestModules;
@@ -40,10 +41,12 @@
4041
import org.junit.jupiter.params.provider.MethodSource;
4142

4243
class DTOConverterTest {
43-
private static final FirstDomainObject FIRST = new FirstDomainObject(Optional.of(1L), ZonedDateTime.parse("2016-04-03T02:01+07:00[Asia/Vientiane]"), "first payload");
44-
private static final FirstDTO FIRST_DTO = new FirstDTO("first", Optional.of(1L), "2016-04-03T02:01+07:00[Asia/Vientiane]", "first payload");
45-
private static final SecondDomainObject SECOND = new SecondDomainObject(UUID.fromString("4a2c853f-7ffc-4ce3-9410-a47e85b3b741"), "second payload");
46-
private static final SecondDTO SECOND_DTO = new SecondDTO("second", "4a2c853f-7ffc-4ce3-9410-a47e85b3b741", "second payload");
44+
private static final Optional<NestedType> NO_CHILD = Optional.empty();
45+
private static final Optional<DTO> NO_CHILD_DTO = Optional.empty();
46+
private static final FirstDomainObject FIRST = new FirstDomainObject(Optional.of(1L), ZonedDateTime.parse("2016-04-03T02:01+07:00[Asia/Vientiane]"), "first payload", NO_CHILD);
47+
private static final FirstDTO FIRST_DTO = new FirstDTO("first", Optional.of(1L), "2016-04-03T02:01+07:00[Asia/Vientiane]", "first payload", NO_CHILD_DTO);
48+
private static final SecondDomainObject SECOND = new SecondDomainObject(UUID.fromString("4a2c853f-7ffc-4ce3-9410-a47e85b3b741"), "second payload", NO_CHILD);
49+
private static final SecondDTO SECOND_DTO = new SecondDTO("second", "4a2c853f-7ffc-4ce3-9410-a47e85b3b741", "second payload", NO_CHILD_DTO);
4750

4851
@SuppressWarnings("unchecked")
4952
@Test

json/src/test/java/org/apache/JsonGenericSerializerTest.java

+26-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@
3030

3131
import org.apache.dto.BaseType;
3232
import org.apache.dto.FirstDomainObject;
33+
import org.apache.dto.FirstNestedType;
34+
import org.apache.dto.NestedType;
3335
import org.apache.dto.SecondDomainObject;
36+
import org.apache.dto.SecondNestedType;
3437
import org.apache.dto.TestModules;
3538
import org.apache.james.json.DTO;
3639
import org.apache.james.json.JsonGenericSerializer;
@@ -40,13 +43,18 @@
4043
import org.junit.jupiter.params.provider.MethodSource;
4144

4245
class JsonGenericSerializerTest {
43-
private static final FirstDomainObject FIRST = new FirstDomainObject(Optional.of(1L), ZonedDateTime.parse("2016-04-03T02:01+07:00[Asia/Vientiane]"), "first payload");
44-
private static final SecondDomainObject SECOND = new SecondDomainObject(UUID.fromString("4a2c853f-7ffc-4ce3-9410-a47e85b3b741"), "second payload");
46+
private static final Optional<NestedType> NO_CHILD = Optional.empty();
47+
private static final FirstDomainObject FIRST = new FirstDomainObject(Optional.of(1L), ZonedDateTime.parse("2016-04-03T02:01+07:00[Asia/Vientiane]"), "first payload", NO_CHILD);
48+
private static final SecondDomainObject SECOND = new SecondDomainObject(UUID.fromString("4a2c853f-7ffc-4ce3-9410-a47e85b3b741"), "second payload", NO_CHILD);
49+
private static final SecondDomainObject SECOND_WITH_NESTED = new SecondDomainObject(UUID.fromString("4a2c853f-7ffc-4ce3-9410-a47e85b3b741"), "second payload", Optional.of(new FirstNestedType(12)));
50+
private static final FirstDomainObject FIRST_WITH_NESTED = new FirstDomainObject(Optional.of(1L), ZonedDateTime.parse("2016-04-03T02:01+07:00[Asia/Vientiane]"), "payload", Optional.of(new SecondNestedType("bar")));
4551

4652
private static final String MISSING_TYPE_JSON = "{\"id\":1,\"time\":\"2016-04-03T02:01+07:00[Asia/Vientiane]\",\"payload\":\"first payload\"}";
4753
private static final String DUPLICATE_TYPE_JSON = "{\"type\":\"first\", \"type\":\"second\", \"id\":1,\"time\":\"2016-04-03T02:01+07:00[Asia/Vientiane]\",\"payload\":\"first payload\"}";
4854
private static final String FIRST_JSON = "{\"type\":\"first\",\"id\":1,\"time\":\"2016-04-03T02:01+07:00[Asia/Vientiane]\",\"payload\":\"first payload\"}";
55+
private static final String FIRST_JSON_WITH_NESTED = "{\"type\":\"first\",\"id\":1,\"time\":\"2016-04-03T02:01+07:00[Asia/Vientiane]\",\"payload\":\"payload\", \"child\": {\"bar\": \"bar\", \"type\": \"second-nested\"}}";
4956
private static final String SECOND_JSON = "{\"type\":\"second\",\"id\":\"4a2c853f-7ffc-4ce3-9410-a47e85b3b741\",\"payload\":\"second payload\"}";
57+
private static final String SECOND_WITH_NESTED_JSON = "{\"type\":\"second\",\"id\":\"4a2c853f-7ffc-4ce3-9410-a47e85b3b741\",\"payload\":\"second payload\", \"child\": {\"foo\": 12, \"type\": \"first-nested\"}}";
5058

5159
@SuppressWarnings("unchecked")
5260
@Test
@@ -56,6 +64,22 @@ void shouldDeserializeKnownType() throws Exception {
5664
.isEqualTo(FIRST);
5765
}
5866

67+
@SuppressWarnings("unchecked")
68+
@Test
69+
void shouldDeserializeNestedTypeWithSecond() throws Exception {
70+
assertThat(JsonGenericSerializer.of(TestModules.FIRST_TYPE, TestModules.SECOND_TYPE, TestModules.FIRST_NESTED, TestModules.SECOND_NESTED)
71+
.deserialize(SECOND_WITH_NESTED_JSON))
72+
.isEqualTo(SECOND_WITH_NESTED);
73+
}
74+
75+
@SuppressWarnings("unchecked")
76+
@Test
77+
void shouldDeserializeNestedTypeWithFirst() throws Exception {
78+
assertThat(JsonGenericSerializer.of(TestModules.FIRST_TYPE, TestModules.SECOND_TYPE, TestModules.FIRST_NESTED, TestModules.SECOND_NESTED)
79+
.deserialize(FIRST_JSON_WITH_NESTED))
80+
.isEqualTo(FIRST_WITH_NESTED);
81+
}
82+
5983
@SuppressWarnings("unchecked")
6084
@Test
6185
void shouldThrowWhenDeserializeEventWithMissingType() {

json/src/test/java/org/apache/dto/FirstDTO.java

+11-3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.Optional;
2424

2525
import org.apache.james.json.DTO;
26+
import org.apache.james.json.DTOConverter;
2627

2728
import com.fasterxml.jackson.annotation.JsonCreator;
2829
import com.fasterxml.jackson.annotation.JsonIgnore;
@@ -33,17 +34,20 @@ public class FirstDTO implements DTO {
3334
private final Optional<Long> id;
3435
private final String time;
3536
private final String payload;
37+
private final Optional<DTO> child;
3638

3739
@JsonCreator
3840
public FirstDTO(
3941
@JsonProperty("type") String type,
4042
@JsonProperty("id") Optional<Long> id,
4143
@JsonProperty("time") String time,
42-
@JsonProperty("payload") String payload) {
44+
@JsonProperty("payload") String payload,
45+
@JsonProperty("child") Optional<DTO> child) {
4346
this.type = type;
4447
this.id = id;
4548
this.time = time;
4649
this.payload = payload;
50+
this.child = child;
4751
}
4852

4953
public String getType() {
@@ -62,8 +66,12 @@ public String getPayload() {
6266
return payload;
6367
}
6468

69+
public Optional<DTO> getChild() {
70+
return child;
71+
}
72+
6573
@JsonIgnore
66-
public FirstDomainObject toDomainObject() {
67-
return new FirstDomainObject(id, ZonedDateTime.parse(time), payload);
74+
public FirstDomainObject toDomainObject(DTOConverter<NestedType, DTO> converter) {
75+
return new FirstDomainObject(id, ZonedDateTime.parse(time), payload, child.flatMap(converter::convert));
6876
}
6977
}

json/src/test/java/org/apache/dto/FirstDomainObject.java

+9-2
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,13 @@ public class FirstDomainObject implements BaseType {
2727
private final Optional<Long> id;
2828
private final ZonedDateTime time;
2929
private final String payload;
30+
private final Optional<NestedType> child;
3031

31-
public FirstDomainObject(Optional<Long> id, ZonedDateTime time, String payload) {
32+
public FirstDomainObject(Optional<Long> id, ZonedDateTime time, String payload, Optional<NestedType> child) {
3233
this.id = id;
3334
this.time = time;
3435
this.payload = payload;
36+
this.child = child;
3537
}
3638

3739
public Optional<Long> getId() {
@@ -46,18 +48,23 @@ public String getPayload() {
4648
return payload;
4749
}
4850

51+
public Optional<NestedType> getChild() {
52+
return child;
53+
}
54+
4955
@Override
5056
public boolean equals(Object o) {
5157
if (this == o) return true;
5258
if (o == null || getClass() != o.getClass()) return false;
5359
FirstDomainObject that = (FirstDomainObject) o;
5460
return Objects.equals(id, that.id) &&
5561
Objects.equals(time, that.time) &&
62+
Objects.equals(child, that.child) &&
5663
Objects.equals(payload, that.payload);
5764
}
5865

5966
@Override
6067
public int hashCode() {
61-
return Objects.hash(id, time, payload);
68+
return Objects.hash(id, time, child, payload);
6269
}
6370
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/****************************************************************
2+
* Licensed to the Apache Software Foundation (ASF) under one *
3+
* or more contributor license agreements. See the NOTICE file *
4+
* distributed with this work for additional information *
5+
* regarding copyright ownership. The ASF licenses this file *
6+
* to you under the Apache License, Version 2.0 (the *
7+
* "License"); you may not use this file except in compliance *
8+
* with the License. You may obtain a copy of the License at *
9+
* *
10+
* http://www.apache.org/licenses/LICENSE-2.0 *
11+
* *
12+
* Unless required by applicable law or agreed to in writing, *
13+
* software distributed under the License is distributed on an *
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
15+
* KIND, either express or implied. See the License for the *
16+
* specific language governing permissions and limitations *
17+
* under the License. *
18+
****************************************************************/
19+
20+
package org.apache.dto;
21+
22+
import org.apache.james.json.DTO;
23+
24+
import com.fasterxml.jackson.annotation.JsonCreator;
25+
import com.fasterxml.jackson.annotation.JsonIgnore;
26+
import com.fasterxml.jackson.annotation.JsonProperty;
27+
28+
public class FirstNestedDTO implements DTO {
29+
private final int foo;
30+
private final String type;
31+
32+
@JsonCreator
33+
public FirstNestedDTO(@JsonProperty("foo") int foo,
34+
@JsonProperty("type") String type) {
35+
this.foo = foo;
36+
this.type = type;
37+
}
38+
39+
public int getFoo() {
40+
return foo;
41+
}
42+
43+
@Override
44+
public String getType() {
45+
return type;
46+
}
47+
48+
@JsonIgnore
49+
public FirstNestedType toDomainObject() {
50+
return new FirstNestedType(foo);
51+
}
52+
53+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/****************************************************************
2+
* Licensed to the Apache Software Foundation (ASF) under one *
3+
* or more contributor license agreements. See the NOTICE file *
4+
* distributed with this work for additional information *
5+
* regarding copyright ownership. The ASF licenses this file *
6+
* to you under the Apache License, Version 2.0 (the *
7+
* "License"); you may not use this file except in compliance *
8+
* with the License. You may obtain a copy of the License at *
9+
* *
10+
* http://www.apache.org/licenses/LICENSE-2.0 *
11+
* *
12+
* Unless required by applicable law or agreed to in writing, *
13+
* software distributed under the License is distributed on an *
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
15+
* KIND, either express or implied. See the License for the *
16+
* specific language governing permissions and limitations *
17+
* under the License. *
18+
****************************************************************/
19+
20+
package org.apache.dto;
21+
22+
import java.util.Objects;
23+
24+
public class FirstNestedType implements NestedType{
25+
final int foo;
26+
27+
public FirstNestedType(int foo) {
28+
this.foo = foo;
29+
}
30+
31+
public int getFoo() {
32+
return foo;
33+
}
34+
35+
@Override
36+
public boolean equals(Object o) {
37+
if (this == o) return true;
38+
if (o == null || getClass() != o.getClass()) return false;
39+
FirstNestedType that = (FirstNestedType) o;
40+
return foo == that.foo;
41+
}
42+
43+
@Override
44+
public int hashCode() {
45+
return Objects.hash(foo);
46+
}
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/****************************************************************
2+
* Licensed to the Apache Software Foundation (ASF) under one *
3+
* or more contributor license agreements. See the NOTICE file *
4+
* distributed with this work for additional information *
5+
* regarding copyright ownership. The ASF licenses this file *
6+
* to you under the Apache License, Version 2.0 (the *
7+
* "License"); you may not use this file except in compliance *
8+
* with the License. You may obtain a copy of the License at *
9+
* *
10+
* http://www.apache.org/licenses/LICENSE-2.0 *
11+
* *
12+
* Unless required by applicable law or agreed to in writing, *
13+
* software distributed under the License is distributed on an *
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
15+
* KIND, either express or implied. See the License for the *
16+
* specific language governing permissions and limitations *
17+
* under the License. *
18+
****************************************************************/
19+
20+
package org.apache.dto;
21+
22+
public interface NestedType {
23+
}

json/src/test/java/org/apache/dto/SecondDTO.java

+12-3
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@
1919

2020
package org.apache.dto;
2121

22+
import java.util.Optional;
2223
import java.util.UUID;
2324

2425
import org.apache.james.json.DTO;
26+
import org.apache.james.json.DTOConverter;
2527

2628
import com.fasterxml.jackson.annotation.JsonCreator;
2729
import com.fasterxml.jackson.annotation.JsonIgnore;
@@ -31,15 +33,18 @@ public class SecondDTO implements DTO {
3133
private final String type;
3234
private final String id;
3335
private final String payload;
36+
private final Optional<DTO> child;
3437

3538
@JsonCreator
3639
public SecondDTO(
3740
@JsonProperty("type") String type,
3841
@JsonProperty("id") String id,
39-
@JsonProperty("payload") String payload) {
42+
@JsonProperty("payload") String payload,
43+
@JsonProperty("child") Optional<DTO> child) {
4044
this.type = type;
4145
this.id = id;
4246
this.payload = payload;
47+
this.child = child;
4348
}
4449

4550
public String getType() {
@@ -54,8 +59,12 @@ public String getPayload() {
5459
return payload;
5560
}
5661

62+
public Optional<DTO> getChild() {
63+
return child;
64+
}
65+
5766
@JsonIgnore
58-
public SecondDomainObject toDomainObject() {
59-
return new SecondDomainObject(UUID.fromString(id), payload);
67+
public SecondDomainObject toDomainObject(DTOConverter<NestedType, DTO> converter) {
68+
return new SecondDomainObject(UUID.fromString(id), payload, child.flatMap(converter::convert));
6069
}
6170
}

json/src/test/java/org/apache/dto/SecondDomainObject.java

+10-2
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,18 @@
2020
package org.apache.dto;
2121

2222
import java.util.Objects;
23+
import java.util.Optional;
2324
import java.util.UUID;
2425

2526
public class SecondDomainObject implements BaseType {
2627
private final UUID id;
2728
private final String payload;
29+
private final Optional<NestedType> child;
2830

29-
public SecondDomainObject(UUID id, String payload) {
31+
public SecondDomainObject(UUID id, String payload, Optional<NestedType> child) {
3032
this.id = id;
3133
this.payload = payload;
34+
this.child = child;
3235
}
3336

3437
public UUID getId() {
@@ -39,17 +42,22 @@ public String getPayload() {
3942
return payload;
4043
}
4144

45+
public Optional<NestedType> getChild() {
46+
return child;
47+
}
48+
4249
@Override
4350
public boolean equals(Object o) {
4451
if (this == o) return true;
4552
if (o == null || getClass() != o.getClass()) return false;
4653
SecondDomainObject that = (SecondDomainObject) o;
4754
return Objects.equals(id, that.id) &&
55+
Objects.equals(child, that.child) &&
4856
Objects.equals(payload, that.payload);
4957
}
5058

5159
@Override
5260
public int hashCode() {
53-
return Objects.hash(id, payload);
61+
return Objects.hash(id, child, payload);
5462
}
5563
}

0 commit comments

Comments
 (0)