View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.juneau.uon;
18  
19  import static org.apache.juneau.TestUtils.*;
20  import static org.apache.juneau.commons.utils.CollectionUtils.*;
21  import static org.junit.jupiter.api.Assertions.*;
22  
23  import java.net.*;
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.junit.jupiter.api.*;
30  
31  class Common_UonTest extends TestBase {
32  	UonParser p = UonParser.DEFAULT;
33  	UonParser pe = UonParser.DEFAULT_DECODING;
34  
35  	//====================================================================================================
36  	// Trim nulls from beans
37  	//====================================================================================================
38  	@Test void a01_trimNullsFromBeans() throws Exception {
39  		var s = UonSerializer.create().encoding();
40  		var t1 = A.create();
41  
42  		var r = s.build().serialize(t1);
43  		assertEquals("(s2=s2)", 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("(s1=null,s2=s2)", r);
50  		t2 = pe.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  	// Trim empty maps
66  	//====================================================================================================
67  	@Test void a02_trimEmptyMaps() throws Exception {
68  		var s = UonSerializer.create().encoding();
69  		var t1 = B.create();
70  		var r = s.build().serialize(t1);
71  
72  		assertEquals("(f1=(),f2=(f2a=null,f2b=(s2=s2)))", r);
73  		var t2 = pe.parse(r, B.class);
74  		assertEquals(json(t2), json(t1));
75  
76  		s.trimEmptyMaps();
77  		r = s.build().serialize(t1);
78  		assertEquals("(f2=(f2a=null,f2b=(s2=s2)))", r);
79  		t2 = pe.parse(r, B.class);
80  		assertNull(t2.f1);
81  	}
82  
83  	public static class B {
84  		public TreeMap<String,A> f1, f2;
85  
86  		public static B create() {
87  			var t = new B();
88  			t.f1 = new TreeMap<>();
89  			t.f2 = new TreeMap<>(){{put("f2a",null);put("f2b",A.create());}};
90  			return t;
91  		}
92  	}
93  
94  	//====================================================================================================
95  	// Trim empty lists
96  	//====================================================================================================
97  	@Test void a03_trimEmptyLists() throws Exception {
98  		var s = UonSerializer.create().encoding();
99  		var t1 = C.create();
100 		var r = s.build().serialize(t1);
101 
102 		assertEquals("(f1=@(),f2=@(null,(s2=s2)))", r);
103 		var t2 = pe.parse(r, C.class);
104 		assertEquals(json(t2), json(t1));
105 
106 		s.trimEmptyCollections();
107 		r = s.build().serialize(t1);
108 		assertEquals("(f2=@(null,(s2=s2)))", r);
109 		t2 = pe.parse(r, C.class);
110 		assertNull(t2.f1);
111 	}
112 
113 	public static class C {
114 		public List<A> f1, f2;
115 
116 		public static C create() {
117 			var t = new C();
118 			t.f1 = l();
119 			t.f2 = l(null,A.create());
120 			return t;
121 		}
122 	}
123 
124 	//====================================================================================================
125 	// Trim empty arrays
126 	//====================================================================================================
127 	@Test void a04_trimEmptyArrays() throws Exception {
128 		var s = UonSerializer.create().encoding();
129 		var t1 = D.create();
130 		var r = s.build().serialize(t1);
131 
132 		assertEquals("(f1=@(),f2=@(null,(s2=s2)))", r);
133 		var t2 = pe.parse(r, D.class);
134 		assertEquals(json(t2), json(t1));
135 
136 		s.trimEmptyCollections();
137 		r = s.build().serialize(t1);
138 		assertEquals("(f2=@(null,(s2=s2)))", r);
139 		t2 = pe.parse(r, D.class);
140 		assertNull(t2.f1);
141 	}
142 
143 	public static class D {
144 		public A[] f1, f2;
145 
146 		public static D create() {
147 			var t = new D();
148 			t.f1 = a();
149 			t.f2 = a(null, A.create());
150 			return t;
151 		}
152 	}
153 
154 	//====================================================================================================
155 	// @Beanp.bpi annotation.
156 	//====================================================================================================
157 	@Test void a05_beanPropertyProperies() throws Exception {
158 		var s = UonSerializer.DEFAULT;
159 		var ue = s.serialize(new E1());
160 		assertEquals("(x1=(f1=1),x2=(f1=1),x3=@((f1=1)),x4=@((f1=1)),x5=@((f1=1)),x6=@((f1=1)))", ue);
161 	}
162 
163 	public static class E1 {
164 		@Beanp(properties="f1") public E2 x1 = new E2();
165 		@Beanp(properties="f1") public Map<String,Integer> x2 = m("f1",1,"f2",2);
166 		@Beanp(properties="f1") public E2[] x3 = {new E2()};
167 		@Beanp(properties="f1") public List<E2> x4 = l(new E2());
168 		@Beanp(properties="f1") public JsonMap[] x5 = {JsonMap.of("f1",1,"f2",2)};
169 		@Beanp(properties="f1") public List<JsonMap> x6 = l(JsonMap.of("f1",1,"f2",2));
170 	}
171 
172 	public static class E2 {
173 		public int f1 = 1;
174 		public int f2 = 2;
175 	}
176 
177 	//====================================================================================================
178 	// @Beanp.bpi annotation on list of beans.
179 	//====================================================================================================
180 	@Test void a06_beanPropertyPropertiesOnListOfBeans() throws Exception {
181 		var s = UonSerializer.DEFAULT;
182 		var l = new LinkedList<>();
183 		var t = new F();
184 		t.x1.add(new F());
185 		l.add(t);
186 		var xml = s.serialize(l);
187 		assertEquals("@((x1=@((x2=2)),x2=2))", xml);
188 	}
189 
190 	public static class F {
191 		@Beanp(properties="x2") public List<F> x1 = new LinkedList<>();
192 		public int x2 = 2;
193 	}
194 
195 	//====================================================================================================
196 	// Test URIAttr - Test that URLs and URIs are serialized and parsed correctly.
197 	//====================================================================================================
198 	@Test void a07_uRIAttr() throws Exception {
199 		var s = UonSerializer.DEFAULT;
200 		var p2 = UonParser.DEFAULT;
201 
202 		var t = new G();
203 		t.uri = new URI("http://uri");
204 		t.f1 = new URI("http://f1");
205 		t.f2 = url("http://f2");
206 
207 		var r = s.serialize(t);
208 		t = p2.parse(r, G.class);
209 		assertEquals("http://uri", t.uri.toString());
210 		assertEquals("http://f1", t.f1.toString());
211 		assertEquals("http://f2", t.f2.toString());
212 	}
213 
214 	public static class G {
215 		public URI uri;
216 		public URI f1;
217 		public URL f2;
218 	}
219 
220 	//====================================================================================================
221 	// Recursion
222 	//====================================================================================================
223 	@Test void a08_recursion() throws Exception {
224 		var s = UonSerializer.create().maxDepth(Integer.MAX_VALUE);
225 
226 		var r1 = new R1();
227 		var r2 = new R2();
228 		var r3 = new R3();
229 		r1.r2 = r2;
230 		r2.r3 = r3;
231 		r3.r1 = r1;
232 
233 		// No recursion detection
234 		assertThrowsWithMessage(Exception.class, "It's recommended you use the BeanTraverseContext.BEANTRAVERSE_detectRecursions setting to help locate the loop.", ()->s.build().serialize(r1));
235 
236 		// Recursion detection, no ignore
237 		s.detectRecursions();
238 		assertThrowsWithMessage(Exception.class, l("$R1", "$R2", "$R3"), ()->s.build().serialize(r1));
239 
240 		s.ignoreRecursions();
241 		assertEquals("(name=foo,r2=(name=bar,r3=(name=baz)))", s.build().serialize(r1));
242 	}
243 
244 	public static class R1 {
245 		public String name = "foo";
246 		public R2 r2;
247 	}
248 	public static class R2 {
249 		public String name = "bar";
250 		public R3 r3;
251 	}
252 	public static class R3 {
253 		public String name = "baz";
254 		public R1 r1;
255 	}
256 }