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