1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.juneau.a.rttests;
18
19 import static java.util.Collections.*;
20 import static org.apache.juneau.TestUtils.*;
21 import static org.apache.juneau.commons.utils.CollectionUtils.*;
22 import static org.apache.juneau.junit.bct.BctAssertions.*;
23
24 import java.util.*;
25
26 import org.apache.juneau.*;
27 import org.apache.juneau.annotation.*;
28 import org.apache.juneau.html.*;
29 import org.apache.juneau.json.*;
30 import org.apache.juneau.msgpack.*;
31 import org.apache.juneau.uon.*;
32 import org.apache.juneau.urlencoding.*;
33 import org.apache.juneau.xml.*;
34 import org.junit.jupiter.params.*;
35 import org.junit.jupiter.params.provider.*;
36
37
38
39
40
41 class RoundTripBeansWithBuilders_Test extends TestBase {
42
43 private static RoundTrip_Tester[] TESTERS = {
44 tester(1, "Json - default")
45 .serializer(JsonSerializer.create().keepNullProperties().addBeanTypes().addRootType())
46 .parser(JsonParser.create())
47 .build(),
48 tester(2, "Json - lax")
49 .serializer(JsonSerializer.create().json5().keepNullProperties().addBeanTypes().addRootType())
50 .parser(JsonParser.create())
51 .build(),
52 tester(3, "Json - lax, readable")
53 .serializer(JsonSerializer.create().json5().ws().keepNullProperties().addBeanTypes().addRootType())
54 .parser(JsonParser.create())
55 .build(),
56 tester(4, "Xml - namespaces, validation, readable")
57 .serializer(XmlSerializer.create().ns().sq().keepNullProperties().addNamespaceUrisToRoot().useWhitespace().addBeanTypes().addRootType())
58 .parser(XmlParser.create())
59 .validateXmlWhitespace()
60 .validateXml()
61 .build(),
62 tester(5, "Xml - no namespaces, validation")
63 .serializer(XmlSerializer.create().sq().keepNullProperties().addBeanTypes().addRootType())
64 .parser(XmlParser.create())
65 .validateXmlWhitespace()
66 .build(),
67 tester(6, "Html - default")
68 .serializer(HtmlSerializer.create().keepNullProperties().addBeanTypes().addRootType())
69 .parser(HtmlParser.create())
70 .validateXmlWhitespace()
71 .build(),
72 tester(7, "Html - readable")
73 .serializer(HtmlSerializer.create().sq().ws().keepNullProperties().addBeanTypes().addRootType())
74 .parser(HtmlParser.create())
75 .validateXmlWhitespace()
76 .build(),
77 tester(8, "Html - with key/value headers")
78 .serializer(HtmlSerializer.create().addKeyValueTableHeaders().addBeanTypes().addRootType())
79 .parser(HtmlParser.create())
80 .validateXmlWhitespace()
81 .build(),
82 tester(9, "Uon - default")
83 .serializer(UonSerializer.create().keepNullProperties().addBeanTypes().addRootType())
84 .parser(UonParser.create())
85 .build(),
86 tester(10, "Uon - readable")
87 .serializer(UonSerializer.create().ws().keepNullProperties().addBeanTypes().addRootType())
88 .parser(UonParser.create())
89 .build(),
90 tester(11, "Uon - encoded")
91 .serializer(UonSerializer.create().encoding().keepNullProperties().addBeanTypes().addRootType())
92 .parser(UonParser.create().decoding())
93 .build(),
94 tester(12, "UrlEncoding - default")
95 .serializer(UrlEncodingSerializer.create().keepNullProperties().addBeanTypes().addRootType())
96 .parser(UrlEncodingParser.create())
97 .build(),
98 tester(13, "UrlEncoding - readable")
99 .serializer(UrlEncodingSerializer.create().ws().keepNullProperties().addBeanTypes().addRootType())
100 .parser(UrlEncodingParser.create())
101 .build(),
102 tester(14, "UrlEncoding - expanded params")
103 .serializer(UrlEncodingSerializer.create().expandedParams().addBeanTypes().addRootType())
104 .parser(UrlEncodingParser.create().expandedParams())
105 .build(),
106 tester(15, "MsgPack")
107 .serializer(MsgPackSerializer.create().keepNullProperties().addBeanTypes().addRootType())
108 .parser(MsgPackParser.create())
109 .build(),
110 tester(16, "Json schema")
111 .serializer(JsonSchemaSerializer.create().keepNullProperties().addBeanTypes().addRootType())
112 .returnOriginalObject()
113 .build(),
114 };
115
116 static RoundTrip_Tester[] testers() {
117 return TESTERS;
118 }
119
120 protected static RoundTrip_Tester.Builder tester(int index, String label) {
121 return RoundTrip_Tester.create(index, label).annotatedClasses(AcConfig.class);
122 }
123
124
125
126
127
128 @ParameterizedTest
129 @MethodSource("testers")
130 void a01_simple(RoundTrip_Tester t) throws Exception {
131 var x = A.builder().f1(1).build();
132 x = t.roundTrip(x, A.class);
133 assertBean(x, "f1", "1");
134 }
135
136 public static class A {
137 private final int f1;
138
139 public A(Builder b) {
140 f1 = b.f1;
141 }
142
143 public static Builder builder() {
144 return new Builder();
145 }
146
147 @Bean(findFluentSetters=true)
148 public static class Builder {
149
150 private int f1;
151 public Builder f1(int v) { f1 = v; return this; }
152
153 public A build() {
154 return new A(this);
155 }
156 }
157
158 public int getF1() { return f1; }
159 }
160
161 @ParameterizedTest
162 @MethodSource("testers")
163 void a02_simple_usingConfig(RoundTrip_Tester t) throws Exception {
164 var x = Ac.builder().f1(1).build();
165 x = t.roundTrip(x, Ac.class);
166 assertBean(x, "f1", "1");
167 }
168
169 @Bean(on="Dummy1", findFluentSetters=true)
170 @Bean(on="Builder", findFluentSetters=true)
171 @Bean(on="Dummy2", findFluentSetters=true)
172 private static class AcConfig {}
173
174 public static class Ac {
175 private final int f1;
176
177 public Ac(Builder b) {
178 f1 = b.f1;
179 }
180
181 public static Builder builder() {
182 return new Builder();
183 }
184
185 public static class Builder {
186
187 private int f1;
188 public Builder f1(int v) { f1 = v; return this; }
189
190 public Ac build() {
191 return new Ac(this);
192 }
193 }
194
195 public int getF1() { return f1; }
196 }
197
198
199
200
201
202 @ParameterizedTest
203 @MethodSource("testers")
204 void a03_beanPropertyBuilder_simple(RoundTrip_Tester t) throws Exception {
205 var x = A2.builder().f1(A.builder().f1(1).build()).build();
206 x = t.roundTrip(x, A2.class);
207 assertBean(x, "f1{f1}", "{1}");
208 }
209
210 public static class A2 {
211 private final A f1;
212
213 public A2(Builder b) {
214 f1 = b.f1;
215 }
216
217 public static Builder builder() {
218 return new Builder();
219 }
220
221 @Bean(findFluentSetters=true)
222 public static class Builder {
223
224 private A f1;
225 public Builder f1(A v) { f1 = v; return this; }
226
227 public A2 build() {
228 return new A2(this);
229 }
230 }
231
232 public A getF1() { return f1; }
233 }
234
235
236
237
238
239 @ParameterizedTest
240 @MethodSource("testers")
241 void a04_beanPropertyBuilder_collections(RoundTrip_Tester t) throws Exception {
242
243
244 if (t.label.contains("UrlEncoding - expanded params"))
245 return;
246 var x = A3.builder()
247 .f1(a(A.builder().f1(1).build()))
248 .f2(singletonList(A.builder().f1(2).build()))
249 .f3(singletonList(singletonList(A.builder().f1(3).build())))
250 .f4(singletonList(a(A.builder().f1(4).build())))
251 .f5(singletonList(singletonList(a(A.builder().f1(5).build()))))
252 .f6(singletonMap("foo", A.builder().f1(6).build()))
253 .f7(singletonMap("foo", singletonMap("bar", A.builder().f1(7).build())))
254 .f8(singletonMap("foo", a(A.builder().f1(8).build())))
255 .f9(singletonMap("foo", singletonList(a(A.builder().f1(9).build()))))
256 .build();
257 x = t.roundTrip(x, A3.class);
258 assertJson("{f1:[{f1:1}],f2:[{f1:2}],f3:[[{f1:3}]],f4:[[{f1:4}]],f5:[[[{f1:5}]]],f6:{foo:{f1:6}},f7:{foo:{bar:{f1:7}}},f8:{foo:[{f1:8}]},f9:{foo:[[{f1:9}]]}}", x);
259 }
260
261 @Bean(sort=true)
262 public static class A3 {
263 private final A[] f1;
264
265 private final List<A> f2;
266 private final List<List<A>> f3;
267 private final List<A[]> f4;
268 private final List<List<A[]>> f5;
269
270 private final Map<String,A> f6;
271 private final Map<String,Map<String,A>> f7;
272 private final Map<String,A[]> f8;
273 private final Map<String,List<A[]>> f9;
274
275 public A3(Builder b) {
276 f1 = b.f1;
277 f2 = b.f2;
278 f3 = b.f3;
279 f4 = b.f4;
280 f5 = b.f5;
281 f6 = b.f6;
282 f7 = b.f7;
283 f8 = b.f8;
284 f9 = b.f9;
285 }
286
287 public static Builder builder() {
288 return new Builder();
289 }
290
291 @Bean(findFluentSetters=true)
292 public static class Builder {
293
294 private A[] f1;
295 public Builder f1(A[] v) { f1 = v; return this; }
296
297 private List<A> f2;
298 public Builder f2(List<A> v) { f2 = v; return this; }
299
300 private List<List<A>> f3;
301 public Builder f3(List<List<A>> v) { f3 = v; return this; }
302
303 private List<A[]> f4;
304 public Builder f4(List<A[]> v) { f4 = v; return this; }
305
306 private List<List<A[]>> f5;
307 public Builder f5(List<List<A[]>> v) { f5 = v; return this; }
308
309 private Map<String,A> f6;
310 public Builder f6(Map<String,A> v) { f6 = v; return this; }
311
312 private Map<String,Map<String,A>> f7;
313 public Builder f7(Map<String,Map<String,A>> v) { f7 = v; return this; }
314
315 private Map<String,A[]> f8;
316 public Builder f8(Map<String,A[]> v) { f8 = v; return this; }
317
318 private Map<String,List<A[]>> f9;
319 public Builder f9(Map<String,List<A[]>> v) { f9 = v; return this; }
320
321 public A3 build() {
322 return new A3(this);
323 }
324 }
325
326 public A[] getF1() { return f1; }
327 public List<A> getF2() { return f2; }
328 public List<List<A>> getF3() { return f3; }
329 public List<A[]> getF4() { return f4; }
330 public List<List<A[]>> getF5() { return f5; }
331 public Map<String,A> getF6() { return f6; }
332 public Map<String,Map<String,A>> getF7() { return f7; }
333 public Map<String,A[]> getF8() { return f8; }
334 public Map<String,List<A[]>> getF9() { return f9; }
335 }
336 }