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 
514 	public static class TemplateSwap extends ObjectSwap<Object,Object> {
515 		@Override
516 		public Object swap(BeanSession session, Object o, String template) throws Exception {
517 			return reader(template);
518 		}
519 	}
520 
521 	@Swap(TemplateSwapJson.class)
522 	@Swap(TemplateSwapXml.class)
523 	@Swap(TemplateSwapHtml.class)
524 	@Swap(TemplateSwapUon.class)
525 	@Swap(TemplateSwapUrlEncoding.class)
526 	@Swap(TemplateSwapMsgPack.class)
527 	@Swap(TemplateSwapRdfXml.class)
528 	public static class TestProgrammaticTemplates {}
529 
530 	public static class TemplateSwapJson extends TemplateSwap {
531 		@Override
532 		public MediaType[] forMediaTypes() {
533 			return MediaType.ofAll("*/json5");
534 		}
535 		@Override
536 		public String withTemplate() {
537 			return "JSON";
538 		}
539 	}
540 	public static class TemplateSwapXml extends TemplateSwap {
541 		@Override
542 		public MediaType[] forMediaTypes() {
543 			return MediaType.ofAll("*/xml");
544 		}
545 		@Override
546 		public String withTemplate() {
547 			return "XML";
548 		}
549 	}
550 	public static class TemplateSwapHtml extends TemplateSwap {
551 		@Override
552 		public MediaType[] forMediaTypes() {
553 			return MediaType.ofAll("*/html");
554 		}
555 		@Override
556 		public String withTemplate() {
557 			return "HTML";
558 		}
559 	}
560 	public static class TemplateSwapUon extends TemplateSwap {
561 		@Override
562 		public MediaType[] forMediaTypes() {
563 			return MediaType.ofAll("*/uon");
564 		}
565 		@Override
566 		public String withTemplate() {
567 			return "UON";
568 		}
569 	}
570 	public static class TemplateSwapUrlEncoding extends TemplateSwap {
571 		@Override
572 		public MediaType[] forMediaTypes() {
573 			return MediaType.ofAll("*/x-www-form-urlencoded");
574 		}
575 		@Override
576 		public String withTemplate() {
577 			return "URLENCODING";
578 		}
579 	}
580 	public static class TemplateSwapMsgPack extends TemplateSwap {
581 		@Override
582 		public MediaType[] forMediaTypes() {
583 			return MediaType.ofAll("*/msgpack");
584 		}
585 		@Override
586 		public String withTemplate() {
587 			return "MSGPACK";
588 		}
589 	}
590 	public static class TemplateSwapRdfXml extends TemplateSwap {
591 		@Override
592 		public MediaType[] forMediaTypes() {
593 			return MediaType.ofAll("*/xml+rdf");
594 		}
595 		@Override
596 		public String withTemplate() {
597 			return "RDFXML";
598 		}
599 	}
600 
601 
602 	public static class TestContextSwap {}
603 
604 	public static class ContextSwap extends ObjectSwap<TestContextSwap,Object> {
605 		@Override
606 		public Object swap(BeanSession session, TestContextSwap o, String template) throws Exception {
607 			return reader(template);
608 		}
609 		@Override
610 		public String withTemplate() {
611 			return "TEMPLATE";
612 		}
613 	}
614 
615 	public static class TestContextSwaps {}
616 
617 	public static class ContextSwapJson extends ObjectSwap<TestContextSwaps,Object> {
618 		@Override
619 		public Object swap(BeanSession session, TestContextSwaps o, String template) throws Exception {
620 			return reader(template);
621 		}
622 		@Override
623 		public MediaType[] forMediaTypes() {
624 			return MediaType.ofAll("*/json5");
625 		}
626 		@Override
627 		public String withTemplate() {
628 			return "JSON";
629 		}
630 	}
631 	public static class ContextSwapXml extends ObjectSwap<TestContextSwaps,Object> {
632 		@Override
633 		public Object swap(BeanSession session, TestContextSwaps o, String template) throws Exception {
634 			return reader(template);
635 		}
636 		@Override
637 		public MediaType[] forMediaTypes() {
638 			return MediaType.ofAll("*/xml");
639 		}
640 		@Override
641 		public String withTemplate() {
642 			return "XML";
643 		}
644 	}
645 	public static class ContextSwapHtml extends ObjectSwap<TestContextSwaps,Object> {
646 		@Override
647 		public Object swap(BeanSession session, TestContextSwaps o, String template) throws Exception {
648 			return reader(template);
649 		}
650 		@Override
651 		public MediaType[] forMediaTypes() {
652 			return MediaType.ofAll("*/html");
653 		}
654 		@Override
655 		public String withTemplate() {
656 			return "HTML";
657 		}
658 	}
659 	public static class ContextSwapUon extends ObjectSwap<TestContextSwaps,Object> {
660 		@Override
661 		public Object swap(BeanSession session, TestContextSwaps o, String template) throws Exception {
662 			return reader(template);
663 		}
664 		@Override
665 		public MediaType[] forMediaTypes() {
666 			return MediaType.ofAll("*/uon");
667 		}
668 		@Override
669 		public String withTemplate() {
670 			return "UON";
671 		}
672 	}
673 	public static class ContextSwapUrlEncoding extends ObjectSwap<TestContextSwaps,Object> {
674 		@Override
675 		public Object swap(BeanSession session, TestContextSwaps o, String template) throws Exception {
676 			return reader(template);
677 		}
678 		@Override
679 		public MediaType[] forMediaTypes() {
680 			return MediaType.ofAll("*/x-www-form-urlencoded");
681 		}
682 		@Override
683 		public String withTemplate() {
684 			return "URLENCODING";
685 		}
686 	}
687 	public static class ContextSwapMsgPack extends ObjectSwap<TestContextSwaps,Object> {
688 		@Override
689 		public Object swap(BeanSession session, TestContextSwaps o, String template) throws Exception {
690 			return reader(template);
691 		}
692 		@Override
693 		public MediaType[] forMediaTypes() {
694 			return MediaType.ofAll("*/msgpack");
695 		}
696 		@Override
697 		public String withTemplate() {
698 			return "MSGPACK";
699 		}
700 	}
701 	public static class ContextSwapRdfXml extends ObjectSwap<TestContextSwaps,Object> {
702 		@Override
703 		public Object swap(BeanSession session, TestContextSwaps o, String template) throws Exception {
704 			return reader(template);
705 		}
706 		@Override
707 		public MediaType[] forMediaTypes() {
708 			return MediaType.ofAll("*/xml+rdf");
709 		}
710 		@Override
711 		public String withTemplate() {
712 			return "RDFXML";
713 		}
714 	}
715 
716 	@Swap(value=BeanSwap.class, mediaTypes={"*/json5"})
717 	@Swap(value=BeanSwap.class, mediaTypes={"*/xml"})
718 	@Swap(value=BeanSwap.class, mediaTypes={"*/html"})
719 	public static class BeanA {
720 		public int f = 1;
721 	}
722 
723 	@Swap(value=BeanSwap.class, mediaTypes={"*/uon"})
724 	@Swap(value=BeanSwap.class, mediaTypes={"*/x-www-form-urlencoded"})
725 	@Swap(value=BeanSwap.class, mediaTypes={"*/msgpack"})
726 	@Swap(value=BeanSwap.class, mediaTypes={"*/xml+rdf"})
727 	public static class BeanB {
728 		public int f = 1;
729 	}
730 
731 	public static class BeanSwap extends ObjectSwap<Object,Object> {
732 		@Override
733 		public Object swap(BeanSession session, Object o, String template) throws Exception {
734 			return reader("SWAPPED");
735 		}
736 	}
737 }