1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.betwixt;
18
19 import java.io.ByteArrayOutputStream;
20 import java.io.PrintStream;
21 import java.io.StringWriter;
22 import java.util.ArrayList;
23 import java.util.Collection;
24
25 import junit.framework.Test;
26 import junit.framework.TestSuite;
27 import junit.textui.TestRunner;
28
29 import org.apache.commons.betwixt.io.BeanWriter;
30 import org.apache.commons.betwixt.io.CyclicReferenceException;
31 import org.apache.commons.betwixt.strategy.CapitalizeNameMapper;
32 import org.apache.commons.betwixt.strategy.HyphenatedNameMapper;
33 import org.apache.commons.logging.impl.SimpleLog;
34
35 /*** Test harness for the BeanWriter
36 *
37 * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
38 * @author <a href="mailto:martin@mvdb.net">Martin van den Bemt</a>
39 * @version $Revision: 1.13 $
40 */
41 public class TestBeanWriter extends AbstractTestCase {
42
43 public static void main( String[] args ) {
44 TestRunner.run( suite() );
45 }
46
47 public static Test suite() {
48 return new TestSuite(TestBeanWriter.class);
49 }
50
51 public TestBeanWriter(String testName) {
52 super(testName);
53 }
54
55 public void testBeanWriter() throws Exception {
56 Object bean = createBean();
57
58 System.out.println( "Now trying pretty print" );
59
60 BeanWriter writer = new BeanWriter();
61 writer.setWriteEmptyElements(true);
62 writer.enablePrettyPrint();
63 writer.write( bean );
64 }
65
66
67 public void testLooping() throws Exception {
68 StringWriter out = new StringWriter();
69 out.write("<?xml version='1.0'?>");
70 BeanWriter writer = new BeanWriter(out);
71 writer.setWriteEmptyElements( true );
72
73
74
75
76
77
78
79
80
81
82
83
84
85 writer.enablePrettyPrint();
86 writer.write( LoopBean.createNoLoopExampleBean() );
87
88 String xml ="<?xml version='1.0'?><LoopBean><name>Root</name><friend><name>level1</name>"
89 + "<friend><name>level2</name><friend><name>level3</name><friend><name>level4</name>"
90 + "<friend><name>level5</name></friend></friend></friend></friend></friend></LoopBean>";
91
92 xmlAssertIsomorphicContent(
93 "Test no loop",
94 parseString(out.getBuffer().toString()),
95 parseString(xml),
96 true);
97
98 out = new StringWriter();
99 out.write("<?xml version='1.0'?>");
100 writer = new BeanWriter(out);
101 writer.setWriteEmptyElements( true );
102 writer.write( LoopBean.createLoopExampleBean() );
103 xml ="<?xml version='1.0'?><LoopBean><name>Root</name><friend><name>level1</name>"
104 + "<friend><name>level2</name><friend><name>level3</name><friend><name>level4</name>"
105 + "<friend><name>level5</name><friend idref='1'/></friend></friend></friend>"
106 + "</friend></friend></LoopBean>";
107 xmlAssertIsomorphicContent(
108 "Test loop",
109 parseString(out.getBuffer().toString()),
110 parseString(xml),
111 true);
112
113
114
115
116
117
118 out = new StringWriter();
119 out.write("<?xml version='1.0'?>");
120 writer = new BeanWriter(out);
121 writer.setWriteEmptyElements( true );
122 writer.setWriteIDs(false);
123 writer.write( LoopBean.createNoLoopExampleBean() );
124 xml ="<?xml version='1.0'?><LoopBean><name>Root</name><friend><name>level1</name><friend>"
125 + "<name>level2</name><friend><name>level3</name><friend><name>level4</name><friend>"
126 + "<name>level5</name></friend></friend>"
127 + "</friend></friend></friend></LoopBean>";
128
129 xmlAssertIsomorphicContent(
130 "Test no loop, no ids",
131 parseString(out.getBuffer().toString()),
132 parseString(xml),
133 true);
134
135
136
137 out = new StringWriter();
138 out.write("<?xml version='1.0'?>");
139 writer = new BeanWriter(out);
140 writer.setWriteEmptyElements( true );
141 writer.setWriteIDs(false);
142 writer.write( LoopBean.createIdOnlyLoopExampleBean() );
143 xml = "<?xml version='1.0'?><LoopBean><name>Root</name><friend><name>level1</name>"
144 + "<friend><name>level2</name><friend><name>level3</name><friend><name>level4</name>"
145 + "<friend><name>level5</name><friend><name>Root</name></friend></friend>"
146 + "</friend></friend></friend></friend></LoopBean>";
147
148 xmlAssertIsomorphicContent(
149 "Test id only loop",
150 parseString(out.getBuffer().toString()),
151 parseString(xml),
152 true);
153
154 try {
155
156 out = new StringWriter();
157 out.write("<?xml version='1.0'?>");
158 writer = new BeanWriter(out);
159 writer.setWriteEmptyElements( true );
160 writer.setWriteIDs(false);
161 writer.write( LoopBean.createLoopExampleBean() );
162 fail("CyclicReferenceException not thrown!");
163
164 } catch (CyclicReferenceException e) {
165
166 }
167 }
168
169 public void testEscaping() throws Exception {
170
171 ByteArrayOutputStream out = new ByteArrayOutputStream();
172 BeanWriter writer = new BeanWriter(out);
173 writer.setWriteEmptyElements( true );
174 writer.enablePrettyPrint();
175 XMLIntrospector introspector = new XMLIntrospector();
176 introspector.setAttributesForPrimitives(true);
177 writer.setXMLIntrospector(introspector);
178 writer.write(new LoopBean("Escape<LessThan"));
179 writer.write(new LoopBean("Escape>GreaterThan"));
180 writer.write(new LoopBean("Escape&hersand"));
181 writer.write(new LoopBean("Escape'apostrophe"));
182 writer.write(new LoopBean("Escape\"Quote"));
183
184 CustomerBean bean = new CustomerBean();
185 bean.setEmails( new String[] {
186 "Escape<LessThan",
187 "Escape>GreaterThan",
188 "Escape&hersand",
189 "Escape'apostrophe",
190 "Escape\"Quote"} );
191
192
193 bean.setName("Escape<LessThan");
194 AddressBean address = new AddressBean();
195 address.setCode("Escape>GreaterThan");
196 address.setCountry("Escape&hersand");
197 address.setCity("Escape'apostrophe");
198 address.setStreet("Escape\"Quote");
199 bean.setAddress(address);
200
201 writer.write(bean);
202 out.flush();
203 String result = "<?xml version='1.0'?><beans>" + out.toString() + "</beans>";
204
205
206 assertTrue(result.indexOf("<email>Escape<LessThan</email>") > -1 );
207 assertTrue(result.indexOf("<email>Escape>GreaterThan</email>") > -1);
208 assertTrue(result.indexOf("<email>Escape&amphersand</email>") != -1);
209 assertTrue(result.indexOf("<email>Escape'apostrophe</email>") != -1);
210 assertTrue(result.indexOf("<email>Escape\"Quote</email>") != -1);
211
212 assertTrue(result.indexOf("name=\"Escape<LessThan\"") > -1 );
213 assertTrue(result.indexOf("code=\"Escape>GreaterThan\"") > -1);
214 assertTrue(result.indexOf("country=\"Escape&amphersand\"") != -1);
215 assertTrue(result.indexOf("city=\"Escape'apostrophe\"") != -1);
216 assertTrue(result.indexOf("street=\"Escape"Quote\"") != -1);
217
218 String xml="<?xml version='1.0'?><beans> <LoopBean name='Escape<LessThan'/>"
219 + "<LoopBean name='Escape>GreaterThan'/><LoopBean name='Escape&amphersand'/>"
220 + "<LoopBean name='Escape'apostrophe'/><LoopBean name='Escape"Quote'/>"
221 + "<CustomerBean name='Escape<LessThan' time='' date='' bigDecimal='' "
222 + "bigInteger='' timestamp='' ID='' nickName=''>"
223 + "<projectMap/><projectNames/><emails><email>Escape<LessThan</email>"
224 + "<email>Escape>GreaterThan</email><email>Escape&amphersand</email>"
225 + "<email>Escape'apostrophe</email><email>Escape\"Quote</email></emails>"
226 + "<locations/><projectURLs/>"
227 + "<address code='Escape>GreaterThan' city='Escape'apostrophe' "
228 + "country='Escape&amphersand' street='Escape"Quote'/>"
229 + "<numbers/></CustomerBean></beans>";
230
231 xmlAssertIsomorphicContent(
232 "Test escaping ",
233 parseString(result),
234 parseString(xml),
235 true);
236 }
237 /***
238 * Testing valid endofline characters.
239 * It tests if there is a warning on System.err
240 */
241 public void testValidEndOfLine() throws Exception {
242 BeanWriter writer = new BeanWriter();
243 writer.setWriteEmptyElements(true);
244
245
246 PrintStream errStream = System.err;
247 ByteArrayOutputStream warning = new ByteArrayOutputStream();
248 System.setErr(new PrintStream(warning));
249
250
251 writer.setLog( new SimpleLog( "test.betwixt" ) );
252
253
254 writer.setEndOfLine("X");
255 warning.flush();
256 assertTrue(warning.toString().startsWith("[WARN]"));
257 warning.reset();
258 writer.setEndOfLine("\tX");
259 warning.flush();
260 assertTrue(warning.toString().startsWith("[WARN]"));
261 warning.reset();
262
263 writer.setEndOfLine(" ");
264 warning.flush();
265 assertTrue(warning.toString().equals(""));
266 warning.reset();
267
268 System.setErr(errStream);
269 }
270
271 /*** Test simplest case for writing empty elements */
272 public void testSimpleWriteEmptyElements() throws Exception{
273
274 AddressBean bean = new AddressBean();
275 bean.setStreet("Pasture Lane");
276 bean.setCity("Bradford");
277
278
279
280
281
282
283
284
285 StringWriter out = new StringWriter();
286 out.write("<?xml version='1.0'?>");
287 BeanWriter writer = new BeanWriter(out);
288 writer.setWriteEmptyElements(true);
289 writer.setWriteIDs(false);
290 writer.write(bean);
291
292
293 String xml = "<?xml version='1.0'?><AddressBean><street>Pasture Lane</street><city>Bradford</city>"
294 + "<code/><country/></AddressBean>";
295
296
297 xmlAssertIsomorphicContent(parseString(out.getBuffer().toString()),parseString(xml), true);
298
299
300 out = new StringWriter();
301 out.write("<?xml version='1.0'?>");
302 writer = new BeanWriter(out);
303 writer.setWriteEmptyElements(false);
304 writer.setWriteIDs(false);
305
306 writer.write(bean);
307 xml = "<?xml version='1.0'?><AddressBean><street>Pasture Lane</street><city>Bradford</city>"
308 + "</AddressBean>";
309
310
311 xmlAssertIsomorphicContent(parseString(out.getBuffer().toString()),parseString(xml), true);
312 }
313
314 /*** Test nested case for writing empty elements */
315 public void testNestedWriteEmptyElements() throws Exception{
316
317
318 LoopBean root = new LoopBean("base");
319 LoopBean middle = new LoopBean(null);
320 root.setFriend(middle);
321 middle.setFriend(new LoopBean(null));
322
323
324
325
326
327 StringWriter out = new StringWriter();
328 out.write("<?xml version='1.0'?>");
329 BeanWriter writer = new BeanWriter(out);
330 writer.setWriteEmptyElements(true);
331 writer.setWriteIDs(false);
332 writer.write(root);
333
334
335 String xml = "<?xml version='1.0'?><LoopBean><name>base</name><friend><name/><friend><name/></friend>"
336 + "</friend></LoopBean>";
337 xmlAssertIsomorphicContent(parseString(out.getBuffer().toString()),parseString(xml), true);
338
339
340 out = new StringWriter();
341 out.write("<?xml version='1.0'?>");
342 writer = new BeanWriter(out);
343 writer.setWriteEmptyElements(false);
344 writer.setWriteIDs(false);
345 writer.write(root);
346
347
348 xml = "<?xml version='1.0'?><LoopBean><name>base</name></LoopBean>";
349 xmlAssertIsomorphicContent(parseString(out.getBuffer().toString()),parseString(xml), true);
350
351 }
352
353 public void testArrayWrite() throws Exception {
354 ArrayBean bean = new ArrayBean("Rob");
355 bean.addHobby("Hacking open source software");
356 bean.addHobby("Playing cricket");
357 bean.addHobby("Watching rugby league");
358 bean.addHobby("Havin' it large");
359
360 StringWriter out = new StringWriter();
361 out.write("<?xml version='1.0'?>");
362 BeanWriter writer = new BeanWriter(out);
363 writer.setWriteEmptyElements(true);
364 writer.setWriteIDs(false);
365 writer.write(bean);
366
367 String xml = "<?xml version='1.0'?><ArrayBean><name>Rob</name><hobbies>"
368 + "<hobby>Hacking open source software</hobby>"
369 + "<hobby>Playing cricket</hobby>"
370 + "<hobby>Watching rugby league</hobby>"
371 + "<hobby>Havin' it large</hobby>"
372 +"</hobbies></ArrayBean>";
373 xmlAssertIsomorphicContent(
374 parseString(out.getBuffer().toString()),
375 parseString(xml),
376 true);
377
378 String [] array = {"This", "That", "The Other"};
379 out = new StringWriter();
380 out.write("<?xml version='1.0'?>");
381 writer = new BeanWriter(out);
382 writer.setWriteEmptyElements(true);
383 writer.setWriteIDs(false);
384 writer.write(array);
385
386 xml = "<?xml version='1.0'?><Array>"
387 + "<String>This</String>"
388 + "<String>That</String>"
389 + "<String>The Other</String>"
390 +"</Array>";
391
392 xmlAssertIsomorphicContent(
393 parseString(out.getBuffer().toString()),
394 parseString(xml),
395 true);
396 }
397
398
399 /*** Test nested case for writing empty elements */
400 public void testListedWriteEmptyElements() throws Exception {
401 ListOfNames names = new ListOfNames();
402 names.addName(new NameBean("Tom"));
403 names.addName(new NameBean("Dick"));
404 names.addName(new NameBean("Harry"));
405 names.addName(new NameBean(""));
406
407 StringWriter out = new StringWriter();
408 out.write("<?xml version='1.0'?>");
409
410 BeanWriter writer = new BeanWriter(out);
411
412
413
414
415
416
417
418
419
420
421
422
423
424 writer.setWriteEmptyElements(false);
425 writer.getXMLIntrospector().setWrapCollectionsInElement(false);
426 writer.setWriteIDs(false);
427 writer.write("Names", names);
428
429 String xml = "<?xml version='1.0'?><Names>"
430 + "<name><name>Tom</name></name>"
431 + "<name><name>Dick</name></name>"
432 + "<name><name>Harry</name></name>"
433 +"</Names>";
434
435 xmlAssertIsomorphicContent(
436 parseString(out.getBuffer().toString()),
437 parseString(xml),
438 true);
439
440 out = new StringWriter();
441 out.write("<?xml version='1.0'?>");
442
443 writer = new BeanWriter(out);
444 writer.setWriteEmptyElements(true);
445 writer.getXMLIntrospector().setWrapCollectionsInElement(false);
446 writer.setWriteIDs(false);
447 writer.write("Names", names);
448
449 xml = "<?xml version='1.0'?><Names>"
450 + "<name><name>Tom</name></name>"
451 + "<name><name>Dick</name></name>"
452 + "<name><name>Harry</name></name>"
453 + "<name><name/></name>"
454 +"</Names>";
455
456 xmlAssertIsomorphicContent(
457 parseString(out.getBuffer().toString()),
458 parseString(xml),
459 true);
460
461 out = new StringWriter();
462 out.write("<?xml version='1.0'?>");
463
464 writer = new BeanWriter(out);
465 writer.setWriteEmptyElements(true);
466 writer.getXMLIntrospector().setWrapCollectionsInElement(true);
467 writer.setWriteIDs(false);
468 writer.write("Names", names);
469
470 xml = "<?xml version='1.0'?><Names><names>"
471 + "<name><name>Tom</name></name>"
472 + "<name><name>Dick</name></name>"
473 + "<name><name>Harry</name></name>"
474 + "<name><name/></name></names>"
475 +"</Names>";
476
477 xmlAssertIsomorphicContent(
478 parseString(out.getBuffer().toString()),
479 parseString(xml),
480 true);
481
482 out = new StringWriter();
483 out.write("<?xml version='1.0'?>");
484
485 writer = new BeanWriter(out);
486 writer.setWriteEmptyElements(false);
487 writer.getXMLIntrospector().setWrapCollectionsInElement(true);
488 writer.setWriteIDs(false);
489 writer.write("Names", names);
490
491 xml = "<?xml version='1.0'?><Names><names>"
492 + "<name><name>Tom</name></name>"
493 + "<name><name>Dick</name></name>"
494 + "<name><name>Harry</name></name>"
495 + "</names>"
496 +"</Names>";
497
498 xmlAssertIsomorphicContent(
499 parseString(out.getBuffer().toString()),
500 parseString(xml),
501 true);
502
503 }
504
505 public void testWriteNameMapperStrategy() throws Exception {
506 ListOfNames names = new ListOfNames();
507 names.addName(new NameBean("Sid James"));
508 names.addName(new NameBean("Kenneth Williams"));
509 names.addName(new NameBean("Joan Simms"));
510 names.addName(new NameBean("Charles Hawtrey"));
511
512 StringWriter out = new StringWriter();
513 out.write("<?xml version='1.0'?>");
514
515 BeanWriter writer = new BeanWriter(out);
516 writer.setWriteEmptyElements(true);
517 writer.getXMLIntrospector().setWrapCollectionsInElement(true);
518 writer.setWriteIDs(false);
519 writer.write("CarryOn", names);
520
521 String xml = "<?xml version='1.0'?><CarryOn><names>"
522 + "<name><name>Sid James</name></name>"
523 + "<name><name>Kenneth Williams</name></name>"
524 + "<name><name>Joan Simms</name></name>"
525 + "<name><name>Charles Hawtrey</name></name>"
526 + "</names>"
527 +"</CarryOn>";
528
529 xmlAssertIsomorphicContent(
530 parseString(out.getBuffer().toString()),
531 parseString(xml),
532 true);
533
534 out = new StringWriter();
535 out.write("<?xml version='1.0'?>");
536
537 writer = new BeanWriter(out);
538 writer.setWriteEmptyElements(true);
539 writer.getXMLIntrospector().setWrapCollectionsInElement(true);
540 writer.setWriteIDs(false);
541 writer.getXMLIntrospector().setElementNameMapper(new CapitalizeNameMapper());
542 writer.write("CarryOn", names);
543
544 xml = "<?xml version='1.0'?><CarryOn><Names>"
545 + "<Name><Name>Sid James</Name></Name>"
546 + "<Name><Name>Kenneth Williams</Name></Name>"
547 + "<Name><Name>Joan Simms</Name></Name>"
548 + "<Name><Name>Charles Hawtrey</Name></Name>"
549 + "</Names>"
550 +"</CarryOn>";
551
552 xmlAssertIsomorphicContent(
553 parseString(out.getBuffer().toString()),
554 parseString(xml),
555 true);
556
557 ArrayList things = new ArrayList();
558 things.add(new NameBean("Sugar"));
559 things.add(new NameBean("Spice"));
560 things.add(new NameBean("All Things Nice"));
561
562 NoAdderBean bean = new NoAdderBean();
563 bean.setThings(things);
564
565 out = new StringWriter();
566 out.write("<?xml version='1.0'?>");
567 writer = new BeanWriter(out);
568 writer.setWriteEmptyElements(true);
569 writer.getXMLIntrospector().setWrapCollectionsInElement(true);
570 writer.setWriteIDs(false);
571 writer.write(bean);
572
573 xml = "<?xml version='1.0'?><NoAdderBean><things>"
574 + "<NameBean><name>Sugar</name></NameBean>"
575 + "<NameBean><name>Spice</name></NameBean>"
576 + "<NameBean><name>All Things Nice</name></NameBean>"
577 + "</things>"
578 +"</NoAdderBean>";
579
580 xmlAssertIsomorphicContent(
581 parseString(out.getBuffer().toString()),
582 parseString(xml),
583 true);
584
585 out = new StringWriter();
586 out.write("<?xml version='1.0'?>");
587 writer = new BeanWriter(out);
588 writer.setWriteEmptyElements(true);
589 writer.getXMLIntrospector().setWrapCollectionsInElement(true);
590 writer.setWriteIDs(false);
591 writer.getXMLIntrospector().setElementNameMapper(new CapitalizeNameMapper());
592 writer.write(bean);
593
594 xml = "<?xml version='1.0'?><NoAdderBean><Things>"
595 + "<NameBean><Name>Sugar</Name></NameBean>"
596 + "<NameBean><Name>Spice</Name></NameBean>"
597 + "<NameBean><Name>All Things Nice</Name></NameBean>"
598 + "</Things>"
599 +"</NoAdderBean>";
600
601 xmlAssertIsomorphicContent(
602 parseString(out.getBuffer().toString()),
603 parseString(xml),
604 true);
605
606 out = new StringWriter();
607 out.write("<?xml version='1.0'?>");
608 writer = new BeanWriter(out);
609 writer.setWriteEmptyElements(true);
610 writer.getXMLIntrospector().setWrapCollectionsInElement(true);
611 writer.setWriteIDs(false);
612 writer.getXMLIntrospector().setElementNameMapper(new HyphenatedNameMapper(false));
613 writer.write(bean);
614
615 xml = "<?xml version='1.0'?><no-adder-bean><things>"
616 + "<name-bean><name>Sugar</name></name-bean>"
617 + "<name-bean><name>Spice</name></name-bean>"
618 + "<name-bean><name>All Things Nice</name></name-bean>"
619 + "</things>"
620 +"</no-adder-bean>";
621
622 xmlAssertIsomorphicContent(
623 parseString(out.getBuffer().toString()),
624 parseString(xml),
625 true);
626 }
627
628 public void testBeanWriterWorksWithAnAddMethodAndACollection() throws Exception {
629
630 BeanWriter bw = new BeanWriter();
631 try {
632 bw.write(new BeanWithAddMethod());
633 } catch (IllegalArgumentException e) {
634 fail("BeanWriter fails when a method is just called add(<type>) and there is also a collection");
635 }
636 }
637
638
639 public static class BeanWithAddMethod {
640 private Collection x;
641 public void add(Object x)
642 {
643
644 }
645
646 public Collection getX() {
647 return x;
648 }
649
650 public void setX(Collection x) {
651 this.x = x;
652 }
653 }
654 }
655