1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.juneau.xml;
18
19 import static org.apache.juneau.TestUtils.*;
20 import static org.apache.juneau.commons.utils.CollectionUtils.*;
21 import static org.apache.juneau.xml.annotation.XmlFormat.*;
22 import static org.junit.jupiter.api.Assertions.*;
23
24 import java.util.*;
25
26 import org.apache.juneau.*;
27 import org.apache.juneau.annotation.*;
28 import org.apache.juneau.collections.*;
29 import org.apache.juneau.xml.annotation.*;
30 import org.junit.jupiter.api.*;
31
32 class Common_Test extends TestBase {
33
34
35
36
37 @Test void a01_trimNullsFromBeans() throws Exception {
38 var s = XmlSerializer.create().sq();
39 var p = XmlParser.DEFAULT;
40 var t1 = A.create();
41
42 var r = s.build().serialize(t1);
43 assertEquals("<object><s2>s2</s2></object>", r);
44 var t2 = p.parse(r, A.class);
45 assertEquals(json(t2), json(t1));
46
47 s.keepNullProperties();
48 r = s.build().serialize(t1);
49 assertEquals("<object><s1 _type='null'/><s2>s2</s2></object>", r);
50 t2 = p.parse(r, A.class);
51 assertEquals(json(t2), json(t1));
52 }
53
54 public static class A {
55 public String s1, s2;
56
57 public static A create() {
58 var t = new A();
59 t.s2 = "s2";
60 return t;
61 }
62 }
63
64
65
66
67 @Test void a02_trimEmptyMaps() throws Exception {
68 var s = XmlSerializer.create().sq();
69 var p = XmlParser.DEFAULT;
70 var t1 = B.create();
71 var r = s.build().serialize(t1);
72
73 assertEquals("<object><f1/><f2><f2a _type='null'/><f2b><s2>s2</s2></f2b></f2></object>", r);
74 var t2 = p.parse(r, B.class);
75 assertEquals(json(t2), json(t1));
76
77 s.trimEmptyMaps();
78 r = s.build().serialize(t1);
79 assertEquals("<object><f2><f2a _type='null'/><f2b><s2>s2</s2></f2b></f2></object>", r);
80 t2 = p.parse(r, B.class);
81 assertNull(t2.f1);
82 }
83
84 public static class B {
85 public TreeMap<String,A> f1, f2;
86
87 public static B create() {
88 var t = new B();
89 t.f1 = new TreeMap<>();
90 t.f2 = new TreeMap<>(){{put("f2a",null);put("f2b",A.create());}};
91 return t;
92 }
93 }
94
95
96
97
98 @Test void a03_trimEmptyLists() throws Exception {
99 var s = XmlSerializer.create().sq();
100 var p = XmlParser.DEFAULT;
101 var t1 = C.create();
102 var r = s.build().serialize(t1);
103
104 assertEquals("<object><f1></f1><f2><null/><object><s2>s2</s2></object></f2></object>", r);
105 var t2 = p.parse(r, C.class);
106 assertEquals(json(t2), json(t1));
107
108 s.trimEmptyCollections();
109 r = s.build().serialize(t1);
110 assertEquals("<object><f2><null/><object><s2>s2</s2></object></f2></object>", r);
111 t2 = p.parse(r, C.class);
112 assertNull(t2.f1);
113 }
114
115 public static class C {
116 public List<A> f1, f2;
117
118 public static C create() {
119 var t = new C();
120 t.f1 = l();
121 t.f2 = l(null,A.create());
122 return t;
123 }
124 }
125
126
127
128
129 @Test void a04_trimEmptyArrays() throws Exception {
130 var s = XmlSerializer.create().sq();
131 var p = XmlParser.DEFAULT;
132 var t1 = D.create();
133 var r = s.build().serialize(t1);
134
135 assertEquals("<object><f1></f1><f2><null/><object><s2>s2</s2></object></f2></object>", r);
136 var t2 = p.parse(r, D.class);
137 assertEquals(json(t2), json(t1));
138
139 s.trimEmptyCollections();
140 r = s.build().serialize(t1);
141 assertEquals("<object><f2><null/><object><s2>s2</s2></object></f2></object>", r);
142 t2 = p.parse(r, D.class);
143 assertNull(t2.f1);
144 }
145
146 public static class D {
147 public A[] f1, f2;
148
149 public static D create() {
150 var t = new D();
151 t.f1 = a();
152 t.f2 = a(null, A.create());
153 return t;
154 }
155 }
156
157
158
159
160 @Test void a05_beanPropertyProperties() throws Exception {
161 var s = XmlSerializer.DEFAULT_SQ;
162 var t = new E1();
163 var r = s.serialize(t);
164 assertEquals(
165 "<object>"
166 +"<x1 f2='2'><f1>1</f1></x1>"
167 +"<x2><f1>1</f1></x2>"
168 +"<x3><object f2='2'><f1>1</f1></object></x3>"
169 +"<x4><object f2='2'><f1>1</f1></object></x4>"
170 +"<x5><object><f1 _type='number'>1</f1></object></x5>"
171 +"<x6><object><f1 _type='number'>1</f1></object></x6>"
172 +"</object>",
173 r);
174 validateXml(t);
175 }
176
177 public static class E1 {
178 @Beanp(properties="f1,f2") public E2 x1 = new E2();
179 @Beanp(properties="f1,f2") public Map<String,Integer> x2 = m("f1",1,"f3",3);
180 @Beanp(properties="f1,f2") public E2[] x3 = {new E2()};
181 @Beanp(properties="f1,f2") public List<E2> x4 = l(new E2());
182 @Beanp(properties="f1") public JsonMap[] x5 = {JsonMap.of("f1",1,"f3",3)};
183 @Beanp(properties="f1") public List<JsonMap> x6 = l(JsonMap.of("f1",1,"f3",3));
184 }
185
186 public static class E2 {
187 public int f1 = 1;
188 @Xml(format=ATTR) public int f2 = 2;
189 public int f3 = 3;
190 @Xml(format=ATTR) public int f4 = 4;
191 }
192
193
194
195
196 @Test void a06_beanPropertyPropertiesOnListOfBeans() throws Exception {
197 var s = XmlSerializer.DEFAULT_SQ;
198 var l = new LinkedList<>();
199 var t = new Test7b();
200 t.x1.add(new Test7b());
201 l.add(t);
202 var xml = s.serialize(l);
203 assertEquals("<array><object><x1><object><x2>2</x2></object></x1><x2>2</x2></object></array>", xml);
204 }
205
206 public static class Test7b {
207 @Beanp(properties="x2") public List<Test7b> x1 = new LinkedList<>();
208 public int x2 = 2;
209 }
210
211
212
213
214 @Test void a07_recursion() throws Exception {
215 var s = XmlSerializer.create().maxDepth(Integer.MAX_VALUE);
216
217 var r1 = new R1();
218 var r2 = new R2();
219 var r3 = new R3();
220 r1.r2 = r2;
221 r2.r3 = r3;
222 r3.r1 = r1;
223
224
225 assertThrowsWithMessage(Exception.class, "It's recommended you use the BeanTraverseContext.BEANTRAVERSE_detectRecursions setting to help locate the loop.", ()->s.build().serialize(r1));
226
227
228 s.detectRecursions();
229 assertThrowsWithMessage(
230 Exception.class,
231 l("[0] <noname>:org.apache.juneau.xml.Common_Test$R1", "->[1] r2:org.apache.juneau.xml.Common_Test$R2", "->[2] r3:org.apache.juneau.xml.Common_Test$R3", "->[3] r1:org.apache.juneau.xml.Common_Test$R1"),
232 ()->s.build().serialize(r1)
233 );
234
235 s.ignoreRecursions();
236 assertEquals("<object><name>foo</name><r2><name>bar</name><r3><name>baz</name></r3></r2></object>", s.build().serialize(r1));
237 }
238
239 public static class R1 {
240 public String name = "foo";
241 public R2 r2;
242 }
243 public static class R2 {
244 public String name = "bar";
245 public R3 r3;
246 }
247 public static class R3 {
248 public String name = "baz";
249 public R1 r1;
250 }
251
252
253
254
255
256 @Test
257 void a08_beanpFormat() throws Exception {
258 var s = XmlSerializer.create().sq().sortProperties().build();
259
260 var bean = new K();
261 var xml = s.serialize(bean);
262
263
264 assertTrue(xml.contains("<doubleField>2.718</doubleField>"));
265 assertTrue(xml.contains("<floatField>3.14</floatField>"));
266 assertTrue(xml.contains("<floatWithCurrency>$19.99</floatWithCurrency>"));
267 assertTrue(xml.contains("<hexField>0xFF00FF</hexField>"));
268 assertTrue(xml.contains("<intField>00042</intField>"));
269 assertTrue(xml.contains("<longField>0000001234567890</longField>"));
270 assertTrue(xml.contains("<name>Test</name>"));
271 assertTrue(xml.contains("<privateField>9.88</privateField>"));
272 assertTrue(xml.contains("<scientificField>6.022e+23</scientificField>") || xml.contains("<scientificField>6.022E+23</scientificField>"));
273 }
274
275 public static class K {
276 @Beanp(format="%.2f")
277 public float floatField = 3.14159f;
278
279 @Beanp(format="$%.2f")
280 public float floatWithCurrency = 19.987f;
281
282 @Beanp(format="%.3f")
283 public double doubleField = 2.71828;
284
285 @Beanp(format="%05d")
286 public int intField = 42;
287
288 @Beanp(format="%016d")
289 public long longField = 1234567890L;
290
291 @Beanp(format="0x%06X")
292 public int hexField = 0xFF00FF;
293
294 @Beanp(format="%.3e")
295 public double scientificField = 6.02214076e23;
296
297 public String name = "Test";
298
299 @Beanp(format="%.2f")
300 private float privateField = 9.876f;
301
302 public float getPrivateField() { return privateField; }
303 public void setPrivateField(float f) { privateField = f; }
304 }
305 }