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.transforms;
18  
19  import static org.apache.juneau.assertions.Verify.*;
20  
21  import java.lang.reflect.*;
22  
23  import org.apache.juneau.*;
24  import org.apache.juneau.annotation.*;
25  
26  class Builder_ComboRoundTripTest extends ComboRoundTripTest_Base {
27  
28  	private static <T> ComboRoundTrip_Tester.Builder<T> tester(int index, String label, Type type, T bean) {
29  		return ComboRoundTrip_Tester.create(index, label, type, ()->bean);
30  	}
31  
32  	private static ComboRoundTrip_Tester<?>[] TESTERS = {
33  		tester(1, "A", A.class, new A(null).init())
34  			.json("{a:1}")
35  			.jsonT("{a:1}")
36  			.jsonR("{\n\ta: 1\n}")
37  			.xml("<object><a>1</a></object>")
38  			.xmlT("<object><a>1</a></object>")
39  			.xmlR("<object>\n\t<a>1</a>\n</object>\n")
40  			.xmlNs("<object><a>1</a></object>")
41  			.html("<table><tr><td>a</td><td>1</td></tr></table>")
42  			.htmlT("<table><tr><td>a</td><td>1</td></tr></table>")
43  			.htmlR("<table>\n\t<tr>\n\t\t<td>a</td>\n\t\t<td>1</td>\n\t</tr>\n</table>\n")
44  			.uon("(a=1)")
45  			.uonT("(a=1)")
46  			.uonR("(\n\ta=1\n)")
47  			.urlEnc("a=1")
48  			.urlEncT("a=1")
49  			.urlEncR("a=1")
50  			.msgPack("81A16101")
51  			.msgPackT("81A16101")
52  			.rdfXml("<rdf:RDF>\n<rdf:Description>\n<jp:a>1</jp:a>\n</rdf:Description>\n</rdf:RDF>\n")
53  			.rdfXmlT("<rdf:RDF>\n<rdf:Description>\n<jp:a>1</jp:a>\n</rdf:Description>\n</rdf:RDF>\n")
54  			.rdfXmlR("<rdf:RDF>\n  <rdf:Description>\n    <jp:a>1</jp:a>\n  </rdf:Description>\n</rdf:RDF>\n")
55  			.verify(x -> verify(x).isType(A.class))
56  			.verify(x -> verify(x.createdByBuilder).isTrue())
57  			.build(),
58  		tester(2, "B", B.class, new B(null).init())
59  			.json("{a:1}")
60  			.jsonT("{a:1}")
61  			.jsonR("{\n\ta: 1\n}")
62  			.xml("<object><a>1</a></object>")
63  			.xmlT("<object><a>1</a></object>")
64  			.xmlR("<object>\n\t<a>1</a>\n</object>\n")
65  			.xmlNs("<object><a>1</a></object>")
66  			.html("<table><tr><td>a</td><td>1</td></tr></table>")
67  			.htmlT("<table><tr><td>a</td><td>1</td></tr></table>")
68  			.htmlR("<table>\n\t<tr>\n\t\t<td>a</td>\n\t\t<td>1</td>\n\t</tr>\n</table>\n")
69  			.uon("(a=1)")
70  			.uonT("(a=1)")
71  			.uonR("(\n\ta=1\n)")
72  			.urlEnc("a=1")
73  			.urlEncT("a=1")
74  			.urlEncR("a=1")
75  			.msgPack("81A16101")
76  			.msgPackT("81A16101")
77  			.rdfXml("<rdf:RDF>\n<rdf:Description>\n<jp:a>1</jp:a>\n</rdf:Description>\n</rdf:RDF>\n")
78  			.rdfXmlT("<rdf:RDF>\n<rdf:Description>\n<jp:a>1</jp:a>\n</rdf:Description>\n</rdf:RDF>\n")
79  			.rdfXmlR("<rdf:RDF>\n  <rdf:Description>\n    <jp:a>1</jp:a>\n  </rdf:Description>\n</rdf:RDF>\n")
80  			.verify(x -> verify(x).isType(B.class))
81  			.verify(x -> verify(x.createdByBuilder).isTrue())
82  			.build(),
83  		tester(3, "C", C.class, new C(null).init())
84  			.json("{a:1}")
85  			.jsonT("{a:1}")
86  			.jsonR("{\n\ta: 1\n}")
87  			.xml("<object><a>1</a></object>")
88  			.xmlT("<object><a>1</a></object>")
89  			.xmlR("<object>\n\t<a>1</a>\n</object>\n")
90  			.xmlNs("<object><a>1</a></object>")
91  			.html("<table><tr><td>a</td><td>1</td></tr></table>")
92  			.htmlT("<table><tr><td>a</td><td>1</td></tr></table>")
93  			.htmlR("<table>\n\t<tr>\n\t\t<td>a</td>\n\t\t<td>1</td>\n\t</tr>\n</table>\n")
94  			.uon("(a=1)")
95  			.uonT("(a=1)")
96  			.uonR("(\n\ta=1\n)")
97  			.urlEnc("a=1")
98  			.urlEncT("a=1")
99  			.urlEncR("a=1")
100 			.msgPack("81A16101")
101 			.msgPackT("81A16101")
102 			.rdfXml("<rdf:RDF>\n<rdf:Description>\n<jp:a>1</jp:a>\n</rdf:Description>\n</rdf:RDF>\n")
103 			.rdfXmlT("<rdf:RDF>\n<rdf:Description>\n<jp:a>1</jp:a>\n</rdf:Description>\n</rdf:RDF>\n")
104 			.rdfXmlR("<rdf:RDF>\n  <rdf:Description>\n    <jp:a>1</jp:a>\n  </rdf:Description>\n</rdf:RDF>\n")
105 			.verify(x -> verify(x).isType(C.class))
106 			.verify(x -> verify(x.createdByBuilder).isTrue())
107 			.build(),
108 		tester(4, "D", D.class, new D(null).init())
109 			.json("{a:1}")
110 			.jsonT("{a:1}")
111 			.jsonR("{\n\ta: 1\n}")
112 			.xml("<object><a>1</a></object>")
113 			.xmlT("<object><a>1</a></object>")
114 			.xmlR("<object>\n\t<a>1</a>\n</object>\n")
115 			.xmlNs("<object><a>1</a></object>")
116 			.html("<table><tr><td>a</td><td>1</td></tr></table>")
117 			.htmlT("<table><tr><td>a</td><td>1</td></tr></table>")
118 			.htmlR("<table>\n\t<tr>\n\t\t<td>a</td>\n\t\t<td>1</td>\n\t</tr>\n</table>\n")
119 			.uon("(a=1)")
120 			.uonT("(a=1)")
121 			.uonR("(\n\ta=1\n)")
122 			.urlEnc("a=1")
123 			.urlEncT("a=1")
124 			.urlEncR("a=1")
125 			.msgPack("81A16101")
126 			.msgPackT("81A16101")
127 			.rdfXml("<rdf:RDF>\n<rdf:Description>\n<jp:a>1</jp:a>\n</rdf:Description>\n</rdf:RDF>\n")
128 			.rdfXmlT("<rdf:RDF>\n<rdf:Description>\n<jp:a>1</jp:a>\n</rdf:Description>\n</rdf:RDF>\n")
129 			.rdfXmlR("<rdf:RDF>\n  <rdf:Description>\n    <jp:a>1</jp:a>\n  </rdf:Description>\n</rdf:RDF>\n")
130 			.verify(x -> verify(x).isType(D.class))
131 			.verify(x -> verify(x.createdByBuilder).isTrue())
132 			.build(),
133 		tester(5, "E", E.class, new E(null).init())
134 			.json("{a:1}")
135 			.jsonT("{a:1}")
136 			.jsonR("{\n\ta: 1\n}")
137 			.xml("<object><a>1</a></object>")
138 			.xmlT("<object><a>1</a></object>")
139 			.xmlR("<object>\n\t<a>1</a>\n</object>\n")
140 			.xmlNs("<object><a>1</a></object>")
141 			.html("<table><tr><td>a</td><td>1</td></tr></table>")
142 			.htmlT("<table><tr><td>a</td><td>1</td></tr></table>")
143 			.htmlR("<table>\n\t<tr>\n\t\t<td>a</td>\n\t\t<td>1</td>\n\t</tr>\n</table>\n")
144 			.uon("(a=1)")
145 			.uonT("(a=1)")
146 			.uonR("(\n\ta=1\n)")
147 			.urlEnc("a=1")
148 			.urlEncT("a=1")
149 			.urlEncR("a=1")
150 			.msgPack("81A16101")
151 			.msgPackT("81A16101")
152 			.rdfXml("<rdf:RDF>\n<rdf:Description>\n<jp:a>1</jp:a>\n</rdf:Description>\n</rdf:RDF>\n")
153 			.rdfXmlT("<rdf:RDF>\n<rdf:Description>\n<jp:a>1</jp:a>\n</rdf:Description>\n</rdf:RDF>\n")
154 			.rdfXmlR("<rdf:RDF>\n  <rdf:Description>\n    <jp:a>1</jp:a>\n  </rdf:Description>\n</rdf:RDF>\n")
155 			.verify(x -> verify(x).isType(E.class))
156 			.verify(x -> verify(x.createdByBuilder).isTrue())
157 			.build(),
158 		tester(6, "H", H.class, new H(null).init())
159 			.json("{fooBar:1}")
160 			.jsonT("{fooBar:1}")
161 			.jsonR("{\n\tfooBar: 1\n}")
162 			.xml("<object><fooBar>1</fooBar></object>")
163 			.xmlT("<object><fooBar>1</fooBar></object>")
164 			.xmlR("<object>\n\t<fooBar>1</fooBar>\n</object>\n")
165 			.xmlNs("<object><fooBar>1</fooBar></object>")
166 			.html("<table><tr><td>fooBar</td><td>1</td></tr></table>")
167 			.htmlT("<table><tr><td>fooBar</td><td>1</td></tr></table>")
168 			.htmlR("<table>\n\t<tr>\n\t\t<td>fooBar</td>\n\t\t<td>1</td>\n\t</tr>\n</table>\n")
169 			.uon("(fooBar=1)")
170 			.uonT("(fooBar=1)")
171 			.uonR("(\n\tfooBar=1\n)")
172 			.urlEnc("fooBar=1")
173 			.urlEncT("fooBar=1")
174 			.urlEncR("fooBar=1")
175 			.msgPack("81A6666F6F42617201")
176 			.msgPackT("81A6666F6F42617201")
177 			.rdfXml("<rdf:RDF>\n<rdf:Description>\n<jp:fooBar>1</jp:fooBar>\n</rdf:Description>\n</rdf:RDF>\n")
178 			.rdfXmlT("<rdf:RDF>\n<rdf:Description>\n<jp:fooBar>1</jp:fooBar>\n</rdf:Description>\n</rdf:RDF>\n")
179 			.rdfXmlR("<rdf:RDF>\n  <rdf:Description>\n    <jp:fooBar>1</jp:fooBar>\n  </rdf:Description>\n</rdf:RDF>\n")
180 			.verify(x -> verify(x).isType(H.class))
181 			.verify(x -> verify(x.createdByBuilder).isTrue())
182 			.build()
183 	};
184 
185 	static ComboRoundTrip_Tester<?>[] testers() {
186 		return TESTERS;
187 	}
188 
189 	//-----------------------------------------------------------------------------------------------------------------
190 	// Typical builder scenario
191 	//-----------------------------------------------------------------------------------------------------------------
192 
193 	public static class A {
194 		public int a;
195 		boolean createdByBuilder;
196 
197 		public A(ABuilder x) {
198 			if (x != null)
199 				a = x.a;
200 		}
201 
202 		public A init() {
203 			a = 1;
204 			return this;
205 		}
206 
207 		public static ABuilder create() {
208 			return new ABuilder();
209 		}
210 	}
211 
212 	public static class ABuilder {
213 		public int a;
214 
215 		public A build() {
216 			var x = new A(this);
217 			x.createdByBuilder = true;
218 			return x;
219 		}
220 	}
221 
222 	//-----------------------------------------------------------------------------------------------------------------
223 	// Builder detected through POJO constructor.
224 	//-----------------------------------------------------------------------------------------------------------------
225 	public static class B {
226 		public int a;
227 		boolean createdByBuilder;
228 
229 		public B(BBuilder x) {
230 			if (x != null) {
231 				a = x.a;
232 				createdByBuilder = true;
233 			}
234 		}
235 
236 		public B init() {
237 			a = 1;
238 			return this;
239 		}
240 	}
241 
242 	public static class BBuilder implements org.apache.juneau.swap.Builder<B> {
243 		public int a;
244 	}
245 
246 	//-----------------------------------------------------------------------------------------------------------------
247 	// Same as B, but should Builder.build() method.
248 	//-----------------------------------------------------------------------------------------------------------------
249 
250 	public static class C {
251 		public int a;
252 		boolean createdByBuilder;
253 
254 		public C(CBuilder x) {
255 			if (x != null) {
256 				a = x.a;
257 			}
258 		}
259 
260 		public C init() {
261 			a = 1;
262 			return this;
263 		}
264 	}
265 
266 	public static class CBuilder implements org.apache.juneau.swap.Builder<B> {
267 		public int a;
268 
269 		public C build() {
270 			var x = new C(this);
271 			x.createdByBuilder = true;
272 			return x;
273 		}
274 	}
275 
276 	//-----------------------------------------------------------------------------------------------------------------
277 	// @Builder annotation on POJO class.
278 	//-----------------------------------------------------------------------------------------------------------------
279 
280 	@org.apache.juneau.annotation.Builder(DBuilder.class)
281 	public static class D {
282 		public int a;
283 		boolean createdByBuilder;
284 
285 		public D(DBuilder x) {
286 			if (x != null) {
287 				a = x.a;
288 				createdByBuilder = true;
289 			}
290 		}
291 
292 		public D init() {
293 			a = 1;
294 			return this;
295 		}
296 	}
297 
298 	public static class DBuilder {
299 		public int a;
300 	}
301 
302 	//-----------------------------------------------------------------------------------------------------------------
303 	// @Builder annotation on POJO class, but uses build() method on builder.
304 	//-----------------------------------------------------------------------------------------------------------------
305 
306 	@org.apache.juneau.annotation.Builder(EBuilder.class)
307 	public static class E {
308 		public int a;
309 		boolean createdByBuilder;
310 
311 		public E(EBuilder x) {
312 			if (x != null) {
313 				a = x.a;
314 			}
315 		}
316 
317 		public E init() {
318 			a = 1;
319 			return this;
320 		}
321 	}
322 
323 	public static class EBuilder {
324 		public int a;
325 
326 		public E build() {
327 			var x = new E(this);
328 			x.createdByBuilder = true;
329 			return x;
330 		}
331 	}
332 
333 	//-----------------------------------------------------------------------------------------------------------------
334 	// Builder with typical method setters.
335 	//-----------------------------------------------------------------------------------------------------------------
336 
337 	public static class H {
338 		public int fooBar;
339 		boolean createdByBuilder;
340 
341 		public H(HBuilder x) {
342 			if (x != null)
343 				this.fooBar = x.fooBar;
344 		}
345 
346 		public H init() {
347 			fooBar = 1;
348 			return this;
349 		}
350 
351 		public static HBuilder create() {
352 			return new HBuilder();
353 		}
354 	}
355 
356 	public static class HBuilder {
357 		private int fooBar;
358 
359 		public H build() {
360 			var x = new H(this);
361 			x.createdByBuilder = true;
362 			return x;
363 		}
364 
365 		@Beanp
366 		public HBuilder fooBar(int fooBar) {
367 			this.fooBar = fooBar;
368 			return this;
369 		}
370 	}
371 }