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.junit.jupiter.api.Assertions.*;
21  
22  import java.net.*;
23  import java.util.*;
24  
25  import org.apache.juneau.*;
26  import org.apache.juneau.annotation.*;
27  import org.apache.juneau.collections.*;
28  import org.junit.jupiter.api.*;
29  
30  class Common_UonTest extends TestBase {
31  	UonParser p = UonParser.DEFAULT;
32  	UonParser pe = UonParser.DEFAULT_DECODING;
33  
34  	//====================================================================================================
35  	// Trim nulls from beans
36  	//====================================================================================================
37  	@Test void a01_trimNullsFromBeans() throws Exception {
38  		var s = UonSerializer.create().encoding();
39  		var t1 = A.create();
40  
41  		var r = s.build().serialize(t1);
42  		assertEquals("(s2=s2)", r);
43  		var t2 = p.parse(r, A.class);
44  		assertEquals(json(t2), json(t1));
45  
46  		s.keepNullProperties();
47  		r = s.build().serialize(t1);
48  		assertEquals("(s1=null,s2=s2)", r);
49  		t2 = pe.parse(r, A.class);
50  		assertEquals(json(t2), json(t1));
51  	}
52  
53  	public static class A {
54  		public String s1, s2;
55  
56  		public static A create() {
57  			var t = new A();
58  			t.s2 = "s2";
59  			return t;
60  		}
61  	}
62  
63  	//====================================================================================================
64  	// Trim empty maps
65  	//====================================================================================================
66  	@Test void a02_trimEmptyMaps() throws Exception {
67  		var s = UonSerializer.create().encoding();
68  		var t1 = B.create();
69  		var r = s.build().serialize(t1);
70  
71  		assertEquals("(f1=(),f2=(f2a=null,f2b=(s2=s2)))", r);
72  		var t2 = pe.parse(r, B.class);
73  		assertEquals(json(t2), json(t1));
74  
75  		s.trimEmptyMaps();
76  		r = s.build().serialize(t1);
77  		assertEquals("(f2=(f2a=null,f2b=(s2=s2)))", r);
78  		t2 = pe.parse(r, B.class);
79  		assertNull(t2.f1);
80  	}
81  
82  	public static class B {
83  		public TreeMap<String,A> f1, f2;
84  
85  		public static B create() {
86  			var t = new B();
87  			t.f1 = new TreeMap<>();
88  			t.f2 = new TreeMap<>(){{put("f2a",null);put("f2b",A.create());}};
89  			return t;
90  		}
91  	}
92  
93  	//====================================================================================================
94  	// Trim empty lists
95  	//====================================================================================================
96  	@Test void a03_trimEmptyLists() throws Exception {
97  		var s = UonSerializer.create().encoding();
98  		var t1 = C.create();
99  		var r = s.build().serialize(t1);
100 
101 		assertEquals("(f1=@(),f2=@(null,(s2=s2)))", r);
102 		var t2 = pe.parse(r, C.class);
103 		assertEquals(json(t2), json(t1));
104 
105 		s.trimEmptyCollections();
106 		r = s.build().serialize(t1);
107 		assertEquals("(f2=@(null,(s2=s2)))", r);
108 		t2 = pe.parse(r, C.class);
109 		assertNull(t2.f1);
110 	}
111 
112 	public static class C {
113 		public List<A> f1, f2;
114 
115 		public static C create() {
116 			var t = new C();
117 			t.f1 = list();
118 			t.f2 = list(null,A.create());
119 			return t;
120 		}
121 	}
122 
123 	//====================================================================================================
124 	// Trim empty arrays
125 	//====================================================================================================
126 	@Test void a04_trimEmptyArrays() throws Exception {
127 		var s = UonSerializer.create().encoding();
128 		var t1 = D.create();
129 		var r = s.build().serialize(t1);
130 
131 		assertEquals("(f1=@(),f2=@(null,(s2=s2)))", r);
132 		var t2 = pe.parse(r, D.class);
133 		assertEquals(json(t2), json(t1));
134 
135 		s.trimEmptyCollections();
136 		r = s.build().serialize(t1);
137 		assertEquals("(f2=@(null,(s2=s2)))", r);
138 		t2 = pe.parse(r, D.class);
139 		assertNull(t2.f1);
140 	}
141 
142 	public static class D {
143 		public A[] f1, f2;
144 
145 		public static D create() {
146 			var t = new D();
147 			t.f1 = new A[]{};
148 			t.f2 = new A[]{null, A.create()};
149 			return t;
150 		}
151 	}
152 
153 	//====================================================================================================
154 	// @Beanp.bpi annotation.
155 	//====================================================================================================
156 	@Test void a05_beanPropertyProperies() throws Exception {
157 		var s = UonSerializer.DEFAULT;
158 		var ue = s.serialize(new E1());
159 		assertEquals("(x1=(f1=1),x2=(f1=1),x3=@((f1=1)),x4=@((f1=1)),x5=@((f1=1)),x6=@((f1=1)))", ue);
160 	}
161 
162 	public static class E1 {
163 		@Beanp(properties="f1") public E2 x1 = new E2();
164 		@Beanp(properties="f1") public Map<String,Integer> x2 = map("f1",1,"f2",2);
165 		@Beanp(properties="f1") public E2[] x3 = {new E2()};
166 		@Beanp(properties="f1") public List<E2> x4 = list(new E2());
167 		@Beanp(properties="f1") public JsonMap[] x5 = {JsonMap.of("f1",1,"f2",2)};
168 		@Beanp(properties="f1") public List<JsonMap> x6 = list(JsonMap.of("f1",1,"f2",2));
169 	}
170 
171 	public static class E2 {
172 		public int f1 = 1;
173 		public int f2 = 2;
174 	}
175 
176 	//====================================================================================================
177 	// @Beanp.bpi annotation on list of beans.
178 	//====================================================================================================
179 	@Test void a06_beanPropertyPropertiesOnListOfBeans() throws Exception {
180 		var s = UonSerializer.DEFAULT;
181 		var l = new LinkedList<>();
182 		var t = new F();
183 		t.x1.add(new F());
184 		l.add(t);
185 		var xml = s.serialize(l);
186 		assertEquals("@((x1=@((x2=2)),x2=2))", xml);
187 	}
188 
189 	public static class F {
190 		@Beanp(properties="x2") public List<F> x1 = new LinkedList<>();
191 		public int x2 = 2;
192 	}
193 
194 	//====================================================================================================
195 	// Test URIAttr - Test that URLs and URIs are serialized and parsed correctly.
196 	//====================================================================================================
197 	@Test void a07_uRIAttr() throws Exception {
198 		var s = UonSerializer.DEFAULT;
199 		var p2 = UonParser.DEFAULT;
200 
201 		var t = new G();
202 		t.uri = new URI("http://uri");
203 		t.f1 = new URI("http://f1");
204 		t.f2 = url("http://f2");
205 
206 		var r = s.serialize(t);
207 		t = p2.parse(r, G.class);
208 		assertEquals("http://uri", t.uri.toString());
209 		assertEquals("http://f1", t.f1.toString());
210 		assertEquals("http://f2", t.f2.toString());
211 	}
212 
213 	public static class G {
214 		public URI uri;
215 		public URI f1;
216 		public URL f2;
217 	}
218 
219 	//====================================================================================================
220 	// Recursion
221 	//====================================================================================================
222 	@Test void a08_recursion() throws Exception {
223 		var s = UonSerializer.create().maxDepth(Integer.MAX_VALUE);
224 
225 		var r1 = new R1();
226 		var r2 = new R2();
227 		var r3 = new R3();
228 		r1.r2 = r2;
229 		r2.r3 = r3;
230 		r3.r1 = r1;
231 
232 		// No recursion detection
233 		assertThrowsWithMessage(Exception.class, "It's recommended you use the BeanTraverseContext.BEANTRAVERSE_detectRecursions setting to help locate the loop.", ()->s.build().serialize(r1));
234 
235 		// Recursion detection, no ignore
236 		s.detectRecursions();
237 		assertThrowsWithMessage(Exception.class, list("$R1", "$R2", "$R3"), ()->s.build().serialize(r1));
238 
239 		s.ignoreRecursions();
240 		assertEquals("(name=foo,r2=(name=bar,r3=(name=baz)))", s.build().serialize(r1));
241 	}
242 
243 	public static class R1 {
244 		public String name = "foo";
245 		public R2 r2;
246 	}
247 	public static class R2 {
248 		public String name = "bar";
249 		public R3 r3;
250 	}
251 	public static class R3 {
252 		public String name = "baz";
253 		public R1 r1;
254 	}
255 }