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.TestUtils.*;
20  
21  import java.util.function.*;
22  
23  import org.apache.juneau.*;
24  import org.apache.juneau.annotation.*;
25  import org.apache.juneau.swap.*;
26  
27  /**
28   * Exhaustive serialization tests Swap annotation.
29   */
30  class SwapsAnnotation_ComboSerializeTest extends ComboSerializeTest_Base {
31  
32  	private static <T> ComboSerialize_Tester.Builder<T> tester(int index, String label, Supplier<T> bean) {
33  		return ComboSerialize_Tester.create(index, label, bean).serializerApply(s -> s.swaps(
34  				ContextSwap.class,
35  				ContextSwapJson.class,
36  				ContextSwapXml.class,
37  				ContextSwapHtml.class,
38  				ContextSwapUon.class,
39  				ContextSwapUrlEncoding.class,
40  				ContextSwapMsgPack.class,
41  				ContextSwapRdfXml.class
42  			));
43  	}
44  
45  	private static ComboSerialize_Tester<?>[] TESTERS = {
46  		tester(1, "TestMediaTypeLiterals", TestMediaTypeLiterals::new)
47  			.json("'JSON'")
48  			.jsonT("'JSON'")
49  			.jsonR("'JSON'")
50  			.xml("<string>XML</string>")
51  			.xmlT("<string>XML</string>")
52  			.xmlR("<string>XML</string>\n")
53  			.xmlNs("<string>XML</string>")
54  			.html("<string>HTML</string>")
55  			.htmlT("<string>HTML</string>")
56  			.htmlR("<string>HTML</string>")
57  			.uon("UON")
58  			.uonT("UON")
59  			.uonR("UON")
60  			.urlEnc("_value=URLENCODING")
61  			.urlEncT("_value=URLENCODING")
62  			.urlEncR("_value=URLENCODING")
63  			.msgPack("A74D53475041434B")
64  			.msgPackT("A74D53475041434B")
65  			.build(),
66  		tester(2, "TestMediaTypePatterns", TestMediaTypePatterns::new)
67  			.json("'JSON'")
68  			.jsonT("'JSON'")
69  			.jsonR("'JSON'")
70  			.xml("<string>XML</string>")
71  			.xmlT("<string>XML</string>")
72  			.xmlR("<string>XML</string>\n")
73  			.xmlNs("<string>XML</string>")
74  			.html("<string>HTML</string>")
75  			.htmlT("<string>HTML</string>")
76  			.htmlR("<string>HTML</string>")
77  			.uon("UON")
78  			.uonT("UON")
79  			.uonR("UON")
80  			.urlEnc("_value=URLENCODING")
81  			.urlEncT("_value=URLENCODING")
82  			.urlEncR("_value=URLENCODING")
83  			.msgPack("A74D53475041434B")
84  			.msgPackT("A74D53475041434B")
85  			.build(),
86  		tester(3, "TestMediaTypePatternsReversed", TestMediaTypePatternsReversed::new)
87  			.json("'JSON'")
88  			.jsonT("'JSON'")
89  			.jsonR("'JSON'")
90  			.xml("<string>XML</string>")
91  			.xmlT("<string>XML</string>")
92  			.xmlR("<string>XML</string>\n")
93  			.xmlNs("<string>XML</string>")
94  			.html("<string>HTML</string>")
95  			.htmlT("<string>HTML</string>")
96  			.htmlR("<string>HTML</string>")
97  			.uon("UON")
98  			.uonT("UON")
99  			.uonR("UON")
100 			.urlEnc("_value=URLENCODING")
101 			.urlEncT("_value=URLENCODING")
102 			.urlEncR("_value=URLENCODING")
103 			.msgPack("A74D53475041434B")
104 			.msgPackT("A74D53475041434B")
105 			.build(),
106 		tester(4, "TestMediaTypePatternsMulti", TestMediaTypePatternsMulti::new)
107 			.json("'JSON'")
108 			.jsonT("'JSON'")
109 			.jsonR("'JSON'")
110 			.xml("<string>XML</string>")
111 			.xmlT("<string>XML</string>")
112 			.xmlR("<string>XML</string>\n")
113 			.xmlNs("<string>XML</string>")
114 			.html("<string>HTML</string>")
115 			.htmlT("<string>HTML</string>")
116 			.htmlR("<string>HTML</string>")
117 			.uon("UON")
118 			.uonT("UON")
119 			.uonR("UON")
120 			.urlEnc("_value=URLENCODING")
121 			.urlEncT("_value=URLENCODING")
122 			.urlEncR("_value=URLENCODING")
123 			.msgPack("A74D53475041434B")
124 			.msgPackT("A74D53475041434B")
125 			.build(),
126 		// In this case, "text/xml" should NOT match "text/xml+rdf".
127 		tester(5, "TestMediaTypePatternsPartial1", TestMediaTypePatternsPartial1::new)
128 			.json("'JSON'")
129 			.jsonT("'JSON'")
130 			.jsonR("'JSON'")
131 			.xml("<string>XML</string>")
132 			.xmlT("<string>XML</string>")
133 			.xmlR("<string>XML</string>\n")
134 			.xmlNs("<string>XML</string>")
135 			.html("<string>HTML</string>")
136 			.htmlT("<string>HTML</string>")
137 			.htmlR("<string>HTML</string>")
138 			.uon("foo")
139 			.uonT("foo")
140 			.uonR("foo")
141 			.urlEnc("_value=foo")
142 			.urlEncT("_value=foo")
143 			.urlEncR("_value=foo")
144 			.msgPack("A3666F6F")
145 			.msgPackT("A3666F6F")
146 			.build(),
147 		// In this case, "text/xml+rdf" should NOT match "text/xml".
148 		tester(6, "TestMediaTypePatternsPartial2", TestMediaTypePatternsPartial2::new)
149 			.json("'foo'")
150 			.jsonT("'foo'")
151 			.jsonR("'foo'")
152 			.xml("<string>foo</string>")
153 			.xmlT("<string>foo</string>")
154 			.xmlR("<string>foo</string>\n")
155 			.xmlNs("<string>foo</string>")
156 			.html("<string>foo</string>")
157 			.htmlT("<string>foo</string>")
158 			.htmlR("<string>foo</string>")
159 			.uon("UON")
160 			.uonT("UON")
161 			.uonR("UON")
162 			.urlEnc("_value=URLENCODING")
163 			.urlEncT("_value=URLENCODING")
164 			.urlEncR("_value=URLENCODING")
165 			.msgPack("A74D53475041434B")
166 			.msgPackT("A74D53475041434B")
167 			.build(),
168 		// XML and RDF serializers.
169 		tester(7, "TestMediaTypePatternsXmlPlus", TestMediaTypePatternsXmlPlus::new)
170 			.json("'foo'")
171 			.jsonT("'foo'")
172 			.jsonR("'foo'")
173 			.xml("<string>XML</string>")
174 			.xmlT("<string>XML</string>")
175 			.xmlR("<string>XML</string>\n")
176 			.xmlNs("<string>XML</string>")
177 			.html("<string>foo</string>")
178 			.htmlT("<string>foo</string>")
179 			.htmlR("<string>foo</string>")
180 			.uon("foo")
181 			.uonT("foo")
182 			.uonR("foo")
183 			.urlEnc("_value=foo")
184 			.urlEncT("_value=foo")
185 			.urlEncR("_value=foo")
186 			.msgPack("A3666F6F")
187 			.msgPackT("A3666F6F")
188 			.build(),
189 		// XML and RDF serializers.
190 		tester(8, "TestMediaTypePatternsXmlPlusReversed", TestMediaTypePatternsXmlPlusReversed::new)
191 			.json("'foo'")
192 			.jsonT("'foo'")
193 			.jsonR("'foo'")
194 			.xml("<string>XML</string>")
195 			.xmlT("<string>XML</string>")
196 			.xmlR("<string>XML</string>\n")
197 			.xmlNs("<string>XML</string>")
198 			.html("<string>foo</string>")
199 			.htmlT("<string>foo</string>")
200 			.htmlR("<string>foo</string>")
201 			.uon("foo")
202 			.uonT("foo")
203 			.uonR("foo")
204 			.urlEnc("_value=foo")
205 			.urlEncT("_value=foo")
206 			.urlEncR("_value=foo")
207 			.msgPack("A3666F6F")
208 			.msgPackT("A3666F6F")
209 			.build(),
210 		// RDF serializer.
211 		tester(9, "TestMediaTypePatternsRdfPlus", TestMediaTypePatternsRdfPlus::new)
212 			.json("'foo'")
213 			.jsonT("'foo'")
214 			.jsonR("'foo'")
215 			.xml("<string>foo</string>")
216 			.xmlT("<string>foo</string>")
217 			.xmlR("<string>foo</string>\n")
218 			.xmlNs("<string>foo</string>")
219 			.html("<string>foo</string>")
220 			.htmlT("<string>foo</string>")
221 			.htmlR("<string>foo</string>")
222 			.uon("foo")
223 			.uonT("foo")
224 			.uonR("foo")
225 			.urlEnc("_value=foo")
226 			.urlEncT("_value=foo")
227 			.urlEncR("_value=foo")
228 			.msgPack("A3666F6F")
229 			.msgPackT("A3666F6F")
230 			.build(),
231 		tester(10, "TestTemplate", TestTemplate::new)
232 			.json("foo")
233 			.jsonT("foo")
234 			.jsonR("foo")
235 			.xml("foo")
236 			.xmlT("foo")
237 			.xmlR("foo\n")
238 			.xmlNs("foo")
239 			.html("foo")
240 			.htmlT("foo")
241 			.htmlR("foo")
242 			.uon("foo")
243 			.uonT("foo")
244 			.uonR("foo")
245 			.urlEnc("foo")
246 			.urlEncT("foo")
247 			.urlEncR("foo")
248 			.msgPack("666F6F")
249 			.msgPackT("666F6F")
250 			.build(),
251 		tester(11, "TestTemplates", TestTemplates::new)
252 			.json("JSON")
253 			.jsonT("JSON")
254 			.jsonR("JSON")
255 			.xml("XML")
256 			.xmlT("XML")
257 			.xmlR("XML\n")
258 			.xmlNs("XML")
259 			.html("HTML")
260 			.htmlT("HTML")
261 			.htmlR("HTML")
262 			.uon("UON")
263 			.uonT("UON")
264 			.uonR("UON")
265 			.urlEnc("URLENCODING")
266 			.urlEncT("URLENCODING")
267 			.urlEncR("URLENCODING")
268 			.msgPack("4D53475041434B")
269 			.msgPackT("4D53475041434B")
270 			.build(),
271 		tester(12, "TestProgrammaticTemplates", TestProgrammaticTemplates::new)
272 			.json("JSON")
273 			.jsonT("JSON")
274 			.jsonR("JSON")
275 			.xml("XML")
276 			.xmlT("XML")
277 			.xmlR("XML\n")
278 			.xmlNs("XML")
279 			.html("HTML")
280 			.htmlT("HTML")
281 			.htmlR("HTML")
282 			.uon("UON")
283 			.uonT("UON")
284 			.uonR("UON")
285 			.urlEnc("URLENCODING")
286 			.urlEncT("URLENCODING")
287 			.urlEncR("URLENCODING")
288 			.msgPack("4D53475041434B")
289 			.msgPackT("4D53475041434B")
290 			.build(),
291 		tester(13, "TestContextSwap", TestContextSwap::new)
292 			.json("TEMPLATE")
293 			.jsonT("TEMPLATE")
294 			.jsonR("TEMPLATE")
295 			.xml("TEMPLATE")
296 			.xmlT("TEMPLATE")
297 			.xmlR("TEMPLATE\n")
298 			.xmlNs("TEMPLATE")
299 			.html("TEMPLATE")
300 			.htmlT("TEMPLATE")
301 			.htmlR("TEMPLATE")
302 			.uon("TEMPLATE")
303 			.uonT("TEMPLATE")
304 			.uonR("TEMPLATE")
305 			.urlEnc("TEMPLATE")
306 			.urlEncT("TEMPLATE")
307 			.urlEncR("TEMPLATE")
308 			.msgPack("54454D504C415445")
309 			.msgPackT("54454D504C415445")
310 			.build(),
311 		tester(14, "TestContextSwaps", TestContextSwaps::new)
312 			.json("JSON")
313 			.jsonT("JSON")
314 			.jsonR("JSON")
315 			.xml("XML")
316 			.xmlT("XML")
317 			.xmlR("XML\n")
318 			.xmlNs("XML")
319 			.html("HTML")
320 			.htmlT("HTML")
321 			.htmlR("HTML")
322 			.uon("UON")
323 			.uonT("UON")
324 			.uonR("UON")
325 			.urlEnc("URLENCODING")
326 			.urlEncT("URLENCODING")
327 			.urlEncR("URLENCODING")
328 			.msgPack("4D53475041434B")
329 			.msgPackT("4D53475041434B")
330 			.build(),
331 		tester(15, "BeanA", BeanA::new)
332 			.json("SWAPPED")
333 			.jsonT("SWAPPED")
334 			.jsonR("SWAPPED")
335 			.xml("SWAPPED")
336 			.xmlT("SWAPPED")
337 			.xmlR("SWAPPED\n")
338 			.xmlNs("SWAPPED")
339 			.html("SWAPPED")
340 			.htmlT("SWAPPED")
341 			.htmlR("SWAPPED")
342 			.uon("(f=1)")
343 			.uonT("(f=1)")
344 			.uonR("(\n\tf=1\n)")
345 			.urlEnc("f=1")
346 			.urlEncT("f=1")
347 			.urlEncR("f=1")
348 			.msgPack("81A16601")
349 			.msgPackT("81A16601")
350 			.build(),
351 		tester(16, "BeanB", BeanB::new)
352 			.json("{f:1}")
353 			.jsonT("{f:1}")
354 			.jsonR("{\n\tf: 1\n}")
355 			.xml("<object><f>1</f></object>")
356 			.xmlT("<object><f>1</f></object>")
357 			.xmlR("<object>\n\t<f>1</f>\n</object>\n")
358 			.xmlNs("<object><f>1</f></object>")
359 			.html("<table><tr><td>f</td><td>1</td></tr></table>")
360 			.htmlT("<table><tr><td>f</td><td>1</td></tr></table>")
361 			.htmlR("<table>\n\t<tr>\n\t\t<td>f</td>\n\t\t<td>1</td>\n\t</tr>\n</table>\n")
362 			.uon("SWAPPED")
363 			.uonT("SWAPPED")
364 			.uonR("SWAPPED")
365 			.urlEnc("SWAPPED")
366 			.urlEncT("SWAPPED")
367 			.urlEncR("SWAPPED")
368 			.msgPack("53574150504544")
369 			.msgPackT("53574150504544")
370 			.build()
371 	};
372 
373 	static ComboSerialize_Tester<?>[] testers() {
374 		return TESTERS;
375 	}
376 
377 	@Swap(value=SwapJson.class, mediaTypes={"application/json5"})
378 	@Swap(value=SwapXml.class, mediaTypes={"text/xml"})
379 	@Swap(value=SwapHtml.class, mediaTypes={"text/html"})
380 	@Swap(value=SwapUon.class, mediaTypes={"text/uon"})
381 	@Swap(value=SwapUrlEncoding.class, mediaTypes={"application/x-www-form-urlencoded"})
382 	@Swap(value=SwapMsgPack.class, mediaTypes={"octal/msgpack"})
383 	@Swap(value=SwapRdfXml.class, mediaTypes={"text/xml+rdf"})
384 	public static class TestMediaTypeLiterals {}
385 
386 	@Swap(value=SwapJson.class, mediaTypes={"*/json5"})
387 	@Swap(value=SwapXml.class, mediaTypes={"*/xml"})
388 	@Swap(value=SwapHtml.class, mediaTypes={"*/html"})
389 	@Swap(value=SwapUon.class, mediaTypes={"*/uon"})
390 	@Swap(value=SwapUrlEncoding.class, mediaTypes={"*/x-www-form-urlencoded"})
391 	@Swap(value=SwapMsgPack.class, mediaTypes={"*/msgpack"})
392 	@Swap(value=SwapRdfXml.class, mediaTypes={"*/xml+rdf"})
393 	public static class TestMediaTypePatterns {}
394 
395 	@Swap(value=SwapRdfXml.class, mediaTypes={"*/xml+rdf"})
396 	@Swap(value=SwapMsgPack.class, mediaTypes={"*/msgpack"})
397 	@Swap(value=SwapUrlEncoding.class, mediaTypes={"*/x-www-form-urlencoded"})
398 	@Swap(value=SwapUon.class, mediaTypes={"*/uon"})
399 	@Swap(value=SwapHtml.class, mediaTypes={"*/html"})
400 	@Swap(value=SwapXml.class, mediaTypes={"*/xml"})
401 	@Swap(value=SwapJson.class, mediaTypes={"*/json5"})
402 	public static class TestMediaTypePatternsReversed {}
403 
404 	@Swap(value=SwapJson.class, mediaTypes={"*/foo","*/json5","*/bar"})
405 	@Swap(value=SwapXml.class, mediaTypes={"*/foo","*/xml","*/bar"})
406 	@Swap(value=SwapHtml.class, mediaTypes={"*/foo","*/html","*/bar"})
407 	@Swap(value=SwapUon.class, mediaTypes={"*/foo","*/uon","*/bar"})
408 	@Swap(value=SwapUrlEncoding.class, mediaTypes={"*/foo","*/x-www-form-urlencoded","*/bar"})
409 	@Swap(value=SwapMsgPack.class, mediaTypes={"*/foo","*/msgpack","*/bar"})
410 	@Swap(value=SwapRdfXml.class, mediaTypes={"*/foo","*/xml+rdf","*/bar"})
411 	public static class TestMediaTypePatternsMulti {}
412 
413 	@Swap(value=SwapJson.class, mediaTypes={"*/foo","*/json5","*/bar"})
414 	@Swap(value=SwapXml.class, mediaTypes={"*/foo","*/xml","*/bar"})
415 	@Swap(value=SwapHtml.class, mediaTypes={"*/foo","*/html","*/bar"})
416 	public static class TestMediaTypePatternsPartial1 {
417 		@Override
418 		public String toString() {
419 			return "foo";
420 		}
421 	}
422 
423 	@Swap(value=SwapUon.class, mediaTypes={"*/foo","*/uon","*/bar"})
424 	@Swap(value=SwapUrlEncoding.class, mediaTypes={"*/foo","*/x-www-form-urlencoded","*/bar"})
425 	@Swap(value=SwapMsgPack.class, mediaTypes={"*/foo","*/msgpack","*/bar"})
426 	@Swap(value=SwapRdfXml.class, mediaTypes={"*/foo","*/xml+rdf","*/bar"})
427 	public static class TestMediaTypePatternsPartial2 {
428 		@Override
429 		public String toString() {
430 			return "foo";
431 		}
432 	}
433 
434 	@Swap(value=SwapXml.class, mediaTypes={"text/xml+*"})
435 	public static class TestMediaTypePatternsXmlPlus {
436 		@Override
437 		public String toString() {
438 			return "foo";
439 		}
440 	}
441 
442 	@Swap(value=SwapXml.class, mediaTypes={"text/*+xml"})
443 	public static class TestMediaTypePatternsXmlPlusReversed {
444 		@Override
445 		public String toString() {
446 			return "foo";
447 		}
448 	}
449 
450 	@Swap(value=SwapXml.class, mediaTypes={"text/rdf+*"})
451 	public static class TestMediaTypePatternsRdfPlus {
452 		@Override
453 		public String toString() {
454 			return "foo";
455 		}
456 	}
457 
458 	public static class SwapJson extends ObjectSwap<Object,Object> {
459 		@Override
460 		public Object swap(BeanSession session, Object o) throws Exception {
461 			return "JSON";
462 		}
463 	}
464 	public static class SwapXml extends ObjectSwap<Object,Object> {
465 		@Override
466 		public Object swap(BeanSession session, Object o) throws Exception {
467 			return "XML";
468 		}
469 	}
470 	public static class SwapHtml extends ObjectSwap<Object,Object> {
471 		@Override
472 		public Object swap(BeanSession session, Object o) throws Exception {
473 			return "HTML";
474 		}
475 	}
476 	public static class SwapUon extends ObjectSwap<Object,Object> {
477 		@Override
478 		public Object swap(BeanSession session, Object o) throws Exception {
479 			return "UON";
480 		}
481 	}
482 	public static class SwapUrlEncoding extends ObjectSwap<Object,Object> {
483 		@Override
484 		public Object swap(BeanSession session, Object o) throws Exception {
485 			return "URLENCODING";
486 		}
487 	}
488 	public static class SwapMsgPack extends ObjectSwap<Object,Object> {
489 		@Override
490 		public Object swap(BeanSession session, Object o) throws Exception {
491 			return "MSGPACK";
492 		}
493 	}
494 	public static class SwapRdfXml extends ObjectSwap<Object,Object> {
495 		@Override
496 		public Object swap(BeanSession session, Object o) throws Exception {
497 			return "RDFXML";
498 		}
499 	}
500 
501 	@Swap(impl=TemplateSwap.class,template="foo")
502 	public static class TestTemplate {}
503 
504 	@Swap(value=TemplateSwap.class, mediaTypes={"*/json5"}, template="JSON")
505 	@Swap(value=TemplateSwap.class, mediaTypes={"*/xml"}, template="XML")
506 	@Swap(value=TemplateSwap.class, mediaTypes={"*/html"}, template="HTML")
507 	@Swap(value=TemplateSwap.class, mediaTypes={"*/uon"}, template="UON")
508 	@Swap(value=TemplateSwap.class, mediaTypes={"*/x-www-form-urlencoded"}, template="URLENCODING")
509 	@Swap(value=TemplateSwap.class, mediaTypes={"*/msgpack"}, template="MSGPACK")
510 	@Swap(value=TemplateSwap.class, mediaTypes={"*/xml+rdf"}, template="RDFXML")
511 	public static class TestTemplates {}
512 
513 	public static class TemplateSwap extends ObjectSwap<Object,Object> {
514 		@Override
515 		public Object swap(BeanSession session, Object o, String template) throws Exception {
516 			return reader(template);
517 		}
518 	}
519 
520 	@Swap(TemplateSwapJson.class)
521 	@Swap(TemplateSwapXml.class)
522 	@Swap(TemplateSwapHtml.class)
523 	@Swap(TemplateSwapUon.class)
524 	@Swap(TemplateSwapUrlEncoding.class)
525 	@Swap(TemplateSwapMsgPack.class)
526 	@Swap(TemplateSwapRdfXml.class)
527 	public static class TestProgrammaticTemplates {}
528 
529 	public static class TemplateSwapJson extends TemplateSwap {
530 		@Override
531 		public MediaType[] forMediaTypes() {
532 			return MediaType.ofAll("*/json5");
533 		}
534 		@Override
535 		public String withTemplate() {
536 			return "JSON";
537 		}
538 	}
539 	public static class TemplateSwapXml extends TemplateSwap {
540 		@Override
541 		public MediaType[] forMediaTypes() {
542 			return MediaType.ofAll("*/xml");
543 		}
544 		@Override
545 		public String withTemplate() {
546 			return "XML";
547 		}
548 	}
549 	public static class TemplateSwapHtml extends TemplateSwap {
550 		@Override
551 		public MediaType[] forMediaTypes() {
552 			return MediaType.ofAll("*/html");
553 		}
554 		@Override
555 		public String withTemplate() {
556 			return "HTML";
557 		}
558 	}
559 	public static class TemplateSwapUon extends TemplateSwap {
560 		@Override
561 		public MediaType[] forMediaTypes() {
562 			return MediaType.ofAll("*/uon");
563 		}
564 		@Override
565 		public String withTemplate() {
566 			return "UON";
567 		}
568 	}
569 	public static class TemplateSwapUrlEncoding extends TemplateSwap {
570 		@Override
571 		public MediaType[] forMediaTypes() {
572 			return MediaType.ofAll("*/x-www-form-urlencoded");
573 		}
574 		@Override
575 		public String withTemplate() {
576 			return "URLENCODING";
577 		}
578 	}
579 	public static class TemplateSwapMsgPack extends TemplateSwap {
580 		@Override
581 		public MediaType[] forMediaTypes() {
582 			return MediaType.ofAll("*/msgpack");
583 		}
584 		@Override
585 		public String withTemplate() {
586 			return "MSGPACK";
587 		}
588 	}
589 	public static class TemplateSwapRdfXml extends TemplateSwap {
590 		@Override
591 		public MediaType[] forMediaTypes() {
592 			return MediaType.ofAll("*/xml+rdf");
593 		}
594 		@Override
595 		public String withTemplate() {
596 			return "RDFXML";
597 		}
598 	}
599 
600 	public static class TestContextSwap {}
601 
602 	public static class ContextSwap extends ObjectSwap<TestContextSwap,Object> {
603 		@Override
604 		public Object swap(BeanSession session, TestContextSwap o, String template) throws Exception {
605 			return reader(template);
606 		}
607 		@Override
608 		public String withTemplate() {
609 			return "TEMPLATE";
610 		}
611 	}
612 
613 	public static class TestContextSwaps {}
614 
615 	public static class ContextSwapJson extends ObjectSwap<TestContextSwaps,Object> {
616 		@Override
617 		public Object swap(BeanSession session, TestContextSwaps o, String template) throws Exception {
618 			return reader(template);
619 		}
620 		@Override
621 		public MediaType[] forMediaTypes() {
622 			return MediaType.ofAll("*/json5");
623 		}
624 		@Override
625 		public String withTemplate() {
626 			return "JSON";
627 		}
628 	}
629 	public static class ContextSwapXml extends ObjectSwap<TestContextSwaps,Object> {
630 		@Override
631 		public Object swap(BeanSession session, TestContextSwaps o, String template) throws Exception {
632 			return reader(template);
633 		}
634 		@Override
635 		public MediaType[] forMediaTypes() {
636 			return MediaType.ofAll("*/xml");
637 		}
638 		@Override
639 		public String withTemplate() {
640 			return "XML";
641 		}
642 	}
643 	public static class ContextSwapHtml extends ObjectSwap<TestContextSwaps,Object> {
644 		@Override
645 		public Object swap(BeanSession session, TestContextSwaps o, String template) throws Exception {
646 			return reader(template);
647 		}
648 		@Override
649 		public MediaType[] forMediaTypes() {
650 			return MediaType.ofAll("*/html");
651 		}
652 		@Override
653 		public String withTemplate() {
654 			return "HTML";
655 		}
656 	}
657 	public static class ContextSwapUon extends ObjectSwap<TestContextSwaps,Object> {
658 		@Override
659 		public Object swap(BeanSession session, TestContextSwaps o, String template) throws Exception {
660 			return reader(template);
661 		}
662 		@Override
663 		public MediaType[] forMediaTypes() {
664 			return MediaType.ofAll("*/uon");
665 		}
666 		@Override
667 		public String withTemplate() {
668 			return "UON";
669 		}
670 	}
671 	public static class ContextSwapUrlEncoding extends ObjectSwap<TestContextSwaps,Object> {
672 		@Override
673 		public Object swap(BeanSession session, TestContextSwaps o, String template) throws Exception {
674 			return reader(template);
675 		}
676 		@Override
677 		public MediaType[] forMediaTypes() {
678 			return MediaType.ofAll("*/x-www-form-urlencoded");
679 		}
680 		@Override
681 		public String withTemplate() {
682 			return "URLENCODING";
683 		}
684 	}
685 	public static class ContextSwapMsgPack extends ObjectSwap<TestContextSwaps,Object> {
686 		@Override
687 		public Object swap(BeanSession session, TestContextSwaps o, String template) throws Exception {
688 			return reader(template);
689 		}
690 		@Override
691 		public MediaType[] forMediaTypes() {
692 			return MediaType.ofAll("*/msgpack");
693 		}
694 		@Override
695 		public String withTemplate() {
696 			return "MSGPACK";
697 		}
698 	}
699 	public static class ContextSwapRdfXml extends ObjectSwap<TestContextSwaps,Object> {
700 		@Override
701 		public Object swap(BeanSession session, TestContextSwaps o, String template) throws Exception {
702 			return reader(template);
703 		}
704 		@Override
705 		public MediaType[] forMediaTypes() {
706 			return MediaType.ofAll("*/xml+rdf");
707 		}
708 		@Override
709 		public String withTemplate() {
710 			return "RDFXML";
711 		}
712 	}
713 
714 	@Swap(value=BeanSwap.class, mediaTypes={"*/json5"})
715 	@Swap(value=BeanSwap.class, mediaTypes={"*/xml"})
716 	@Swap(value=BeanSwap.class, mediaTypes={"*/html"})
717 	public static class BeanA {
718 		public int f = 1;
719 	}
720 
721 	@Swap(value=BeanSwap.class, mediaTypes={"*/uon"})
722 	@Swap(value=BeanSwap.class, mediaTypes={"*/x-www-form-urlencoded"})
723 	@Swap(value=BeanSwap.class, mediaTypes={"*/msgpack"})
724 	@Swap(value=BeanSwap.class, mediaTypes={"*/xml+rdf"})
725 	public static class BeanB {
726 		public int f = 1;
727 	}
728 
729 	public static class BeanSwap extends ObjectSwap<Object,Object> {
730 		@Override
731 		public Object swap(BeanSession session, Object o, String template) throws Exception {
732 			return reader("SWAPPED");
733 		}
734 	}
735 }