1   /*
2    * Copyright 2001-2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
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          // logging for debugging jsut this method 
74  //        SimpleLog log = new SimpleLog("[testLooping:BeanWriter]");
75  //        log.setLevel(SimpleLog.LOG_LEVEL_TRACE);
76  //        writer.setLog(log);
77          
78  //        log = new SimpleLog("[testLooping:AbstractBeanWriter]");
79  //        log.setLevel(SimpleLog.LOG_LEVEL_TRACE);
80  //        writer.setAbstractBeanWriterLog(log);
81          
82  //        log = new SimpleLog("[testLooping]");
83  //        log.setLevel(SimpleLog.LOG_LEVEL_TRACE);
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         // test not writing IDs
115 
116         
117 //        log.info("Writing LoopBean.createNoLoopExampleBean...");
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 //        log.info("Writing LoopBean.createIdOnlyLoopExampleBean...");
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 //            log.info("Writing LoopBean.createLoopExampleBean...")
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             // everything's fine
167         }
168     }
169     
170     public void testEscaping() throws Exception {
171         //XXX find a way to automatically verify test
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&amphersand"));
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&amphersand",
191                                         "Escape'apostrophe",
192                                         "Escape\"Quote"} );
193                                         
194         // The attribute value escaping needs test too..
195         bean.setName("Escape<LessThan");
196         AddressBean address = new AddressBean();
197         address.setCode("Escape>GreaterThan");
198         address.setCountry("Escape&amphersand");
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         // check for the elemant content..
208         assertTrue(result.indexOf("<email>Escape&lt;LessThan</email>") > -1 );
209         assertTrue(result.indexOf("<email>Escape&gt;GreaterThan</email>") > -1);
210         assertTrue(result.indexOf("<email>Escape&amp;amphersand</email>") != -1);
211         assertTrue(result.indexOf("<email>Escape'apostrophe</email>") != -1);
212         assertTrue(result.indexOf("<email>Escape\"Quote</email>") != -1);
213         // check for the attributes..
214         assertTrue(result.indexOf("name=\"Escape&lt;LessThan\"") > -1 );
215         assertTrue(result.indexOf("code=\"Escape&gt;GreaterThan\"") > -1);
216         assertTrue(result.indexOf("country=\"Escape&amp;amphersand\"") != -1);
217         assertTrue(result.indexOf("city=\"Escape&apos;apostrophe\"") != -1);
218         assertTrue(result.indexOf("street=\"Escape&quot;Quote\"") != -1);
219         
220         String xml="<?xml version='1.0'?><beans>  <LoopBean name='Escape&lt;LessThan'/>"
221             + "<LoopBean name='Escape&gt;GreaterThan'/><LoopBean name='Escape&amp;amphersand'/>"
222             + "<LoopBean name='Escape&apos;apostrophe'/><LoopBean name='Escape&quot;Quote'/>"
223             + "<CustomerBean name='Escape&lt;LessThan' time='' date='' bigDecimal='' "
224             + "bigInteger='' timestamp='' ID='' nickName=''>"
225             + "<projectMap/><projectNames/><emails><email>Escape&lt;LessThan</email>"
226             + "<email>Escape&gt;GreaterThan</email><email>Escape&amp;amphersand</email>"
227             + "<email>Escape'apostrophe</email><email>Escape\"Quote</email></emails>"
228             + "<locations/><projectURLs/>"
229             + "<address code='Escape&gt;GreaterThan' city='Escape&apos;apostrophe' "
230             + "country='Escape&amp;amphersand' street='Escape&quot;Quote'/>"
231             + "<numbers/></CustomerBean></beans>";
232             
233         xmlAssertIsomorphicContent(
234                             "Test escaping ",
235                             parseString(result),
236                             parseString(xml), 
237                             true);  
238     }
239     /***
240      * Testing valid endofline characters.
241      * It tests if there is a warning on System.err
242      */
243     public void testValidEndOfLine() throws Exception {
244         BeanWriter writer = new BeanWriter();
245         writer.setWriteEmptyElements(true);
246         
247         // store the system err
248         PrintStream errStream = System.err;
249         ByteArrayOutputStream warning = new ByteArrayOutputStream();
250         System.setErr(new PrintStream(warning));
251         
252         // force logging to go to System.err
253         writer.setLog( new SimpleLog( "test.betwixt" ) );
254         
255         
256         writer.setEndOfLine("X");
257         warning.flush();
258         assertTrue(warning.toString().startsWith("[WARN]"));
259         warning.reset();
260         writer.setEndOfLine("\tX");
261         warning.flush();
262         assertTrue(warning.toString().startsWith("[WARN]"));
263         warning.reset();
264         // now test a valid value..
265         writer.setEndOfLine(" ");
266         warning.flush();
267         assertTrue(warning.toString().equals(""));
268         warning.reset();
269         // set the System.err back again..
270         System.setErr(errStream);
271     }
272     
273     /*** Test simplest case for writing empty elements */
274     public void testSimpleWriteEmptyElements() throws Exception{
275         // use same bean for both tests
276         AddressBean bean = new AddressBean();
277         bean.setStreet("Pasture Lane");
278         bean.setCity("Bradford");
279         
280 //        SimpleLog log = new SimpleLog( "[SimpleEmpty:AbstractBeanWriter]" );
281 //        log.setLevel(SimpleLog.LOG_LEVEL_TRACE);
282         
283 //        SimpleLog baseLog = new SimpleLog( "[SimpleEmpty]" );
284 //        baseLog.setLevel(SimpleLog.LOG_LEVEL_TRACE);
285         
286         // test output when writing empty elements
287         StringWriter out = new StringWriter();
288         out.write("<?xml version='1.0'?>");
289         BeanWriter writer = new BeanWriter(out);
290         writer.setWriteEmptyElements(true);
291         writer.getBindingConfiguration().setMapIDs(false);
292         writer.write(bean);
293 //        baseLog.debug("SIMPLE EMPTY");
294 //        baseLog.debug(out.getBuffer().toString());
295         String xml = "<?xml version='1.0'?><AddressBean><street>Pasture Lane</street><city>Bradford</city>"
296                     + "<code/><country/></AddressBean>";
297 //        baseLog.debug(xml);
298 
299         xmlAssertIsomorphicContent(parseString(out.getBuffer().toString()),parseString(xml), true);
300         
301         // test output when not writing empty elements
302         out = new StringWriter();
303         out.write("<?xml version='1.0'?>");
304         writer = new BeanWriter(out);
305         writer.setWriteEmptyElements(false);
306         writer.getBindingConfiguration().setMapIDs(false);
307 //        writer.setAbstractBeanWriterLog(log);
308         writer.write(bean);
309         xml = "<?xml version='1.0'?><AddressBean><street>Pasture Lane</street><city>Bradford</city>"
310                     + "</AddressBean>";
311 //        baseLog.debug("SIMPLE NOT EMPTY");
312 //        baseLog.debug(out.getBuffer().toString());
313         xmlAssertIsomorphicContent(parseString(out.getBuffer().toString()),parseString(xml), true);
314     }
315     
316     /*** Test nested case for writing empty elements */
317     public void testNestedWriteEmptyElements() throws Exception{
318         
319         // write same bean both times
320         LoopBean root = new LoopBean("base");
321         LoopBean middle = new LoopBean(null);
322         root.setFriend(middle);
323         middle.setFriend(new LoopBean(null));
324         
325 //        SimpleLog baseLog = new SimpleLog( "[NestedEmpty]" );
326 //        baseLog.setLevel(SimpleLog.LOG_LEVEL_TRACE);
327     
328         // test output when writing empty elements
329         StringWriter out = new StringWriter();
330         out.write("<?xml version='1.0'?>");
331         BeanWriter writer = new BeanWriter(out);
332         writer.setWriteEmptyElements(true);
333         writer.getBindingConfiguration().setMapIDs(false);
334         writer.write(root);
335 //        baseLog.debug("NESTED EMPTY");
336 //        baseLog.debug(out.getBuffer().toString());
337         String xml = "<?xml version='1.0'?><LoopBean><name>base</name><friend><name/><friend><name/></friend>"
338                     + "</friend></LoopBean>";
339         xmlAssertIsomorphicContent(parseString(out.getBuffer().toString()),parseString(xml), true);
340         
341         // test output when not writing empty elements
342         out = new StringWriter();
343         out.write("<?xml version='1.0'?>");
344         writer = new BeanWriter(out);
345         writer.setWriteEmptyElements(false);
346         writer.getBindingConfiguration().setMapIDs(false);
347         writer.write(root);
348 //        baseLog.debug("NESTED NOT EMPTY");
349 //        baseLog.debug(out.getBuffer().toString());
350         xml = "<?xml version='1.0'?><LoopBean><name>base</name></LoopBean>";
351         xmlAssertIsomorphicContent(parseString(out.getBuffer().toString()),parseString(xml), true);
352         
353     }
354     
355     public void testArrayWrite() throws Exception {
356         ArrayBean bean = new ArrayBean("Rob");
357         bean.addHobby("Hacking open source software");
358         bean.addHobby("Playing cricket");
359         bean.addHobby("Watching rugby league");
360         bean.addHobby("Havin' it large");
361     
362         StringWriter out = new StringWriter();
363         out.write("<?xml version='1.0'?>");
364         BeanWriter writer = new BeanWriter(out);
365         writer.setWriteEmptyElements(true);
366         writer.getBindingConfiguration().setMapIDs(false);
367         writer.write(bean);
368         
369         String xml = "<?xml version='1.0'?><ArrayBean><name>Rob</name><hobbies>"
370          + "<hobby>Hacking open source software</hobby>" 
371          + "<hobby>Playing cricket</hobby>" 
372          + "<hobby>Watching rugby league</hobby>" 
373          + "<hobby>Havin' it large</hobby>"
374          +"</hobbies></ArrayBean>";
375         xmlAssertIsomorphicContent(
376                             parseString(out.getBuffer().toString()),
377                             parseString(xml), 
378                             true);
379                             
380         String [] array = {"This", "That", "The Other"};
381         out = new StringWriter();
382         out.write("<?xml version='1.0'?>");
383         writer = new BeanWriter(out);
384         writer.setWriteEmptyElements(true);
385         writer.getBindingConfiguration().setMapIDs(false);
386         writer.write(array);
387         
388         xml = "<?xml version='1.0'?><Array>"
389          + "<String>This</String>" 
390          + "<String>That</String>" 
391          + "<String>The Other</String>" 
392          +"</Array>";
393          
394         xmlAssertIsomorphicContent(
395                             parseString(out.getBuffer().toString()),
396                             parseString(xml), 
397                             true);
398     }
399     
400     
401     /*** Test nested case for writing empty elements */
402     public void testListedWriteEmptyElements() throws Exception {
403         ListOfNames names = new ListOfNames();
404         names.addName(new NameBean("Tom"));
405         names.addName(new NameBean("Dick"));
406         names.addName(new NameBean("Harry"));
407         names.addName(new NameBean(""));
408     
409         StringWriter out = new StringWriter();
410         out.write("<?xml version='1.0'?>");
411 
412         BeanWriter writer = new BeanWriter(out);
413         
414         //SimpleLog log = new SimpleLog("[testListedWriteEmptyElements:AbstractBeanWriter]");
415         //log.setLevel(SimpleLog.LOG_LEVEL_TRACE);
416         //writer.setAbstractBeanWriterLog(log);
417         
418         //log = new SimpleLog("[testListedWriteEmptyElements:XMLIntrospector]");
419         //log.setLevel(SimpleLog.LOG_LEVEL_TRACE);
420         //writer.getXMLIntrospector().setLog(log);
421         
422         //log = new SimpleLog("[testListedWriteEmptyElements:XMLIntrospectorHelper]");
423         //log.setLevel(SimpleLog.LOG_LEVEL_TRACE);
424         //XMLIntrospectorHelper.setLog(log);
425         
426         writer.setWriteEmptyElements(false);
427         writer.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(false);
428         writer.getBindingConfiguration().setMapIDs(false);
429         writer.write("Names", names);
430         
431         String xml = "<?xml version='1.0'?><Names>"
432          + "<name><name>Tom</name></name>" 
433          + "<name><name>Dick</name></name>" 
434          + "<name><name>Harry</name></name>" 
435          +"</Names>";
436          
437         xmlAssertIsomorphicContent(
438                             parseString(out.getBuffer().toString()),
439                             parseString(xml), 
440                             true);
441                             
442         out = new StringWriter();
443         out.write("<?xml version='1.0'?>");
444 
445         writer = new BeanWriter(out);
446         writer.setWriteEmptyElements(true);
447         writer.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(false);
448         writer.getBindingConfiguration().setMapIDs(false);
449         writer.write("Names", names);
450         
451         xml = "<?xml version='1.0'?><Names>"
452          + "<name><name>Tom</name></name>" 
453          + "<name><name>Dick</name></name>" 
454          + "<name><name>Harry</name></name>" 
455          + "<name><name/></name>"
456          +"</Names>";
457          
458         xmlAssertIsomorphicContent(
459                             parseString(out.getBuffer().toString()),
460                             parseString(xml), 
461                             true);
462                             
463         out = new StringWriter();
464         out.write("<?xml version='1.0'?>");
465 
466         writer = new BeanWriter(out);
467         writer.setWriteEmptyElements(true);
468         writer.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(true);
469         writer.getBindingConfiguration().setMapIDs(false);
470         writer.write("Names", names);
471         
472         xml = "<?xml version='1.0'?><Names><names>"
473          + "<name><name>Tom</name></name>" 
474          + "<name><name>Dick</name></name>" 
475          + "<name><name>Harry</name></name>" 
476          + "<name><name/></name></names>"
477          +"</Names>";
478          
479         xmlAssertIsomorphicContent(
480                             parseString(out.getBuffer().toString()),
481                             parseString(xml), 
482                             true);
483                             
484         out = new StringWriter();
485         out.write("<?xml version='1.0'?>");
486 
487         writer = new BeanWriter(out);
488         writer.setWriteEmptyElements(false);
489         writer.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(true);
490         writer.getBindingConfiguration().setMapIDs(false);
491         writer.write("Names", names);
492         
493         xml = "<?xml version='1.0'?><Names><names>"
494          + "<name><name>Tom</name></name>" 
495          + "<name><name>Dick</name></name>" 
496          + "<name><name>Harry</name></name>" 
497          + "</names>"
498          +"</Names>";
499          
500         xmlAssertIsomorphicContent(
501                             parseString(out.getBuffer().toString()),
502                             parseString(xml), 
503                             true);
504                             
505     }
506     
507     public void testWriteNameMapperStrategy() throws Exception {
508         ListOfNames names = new ListOfNames();
509         names.addName(new NameBean("Sid James"));
510         names.addName(new NameBean("Kenneth Williams"));
511         names.addName(new NameBean("Joan Simms"));
512         names.addName(new NameBean("Charles Hawtrey"));
513         
514         StringWriter out = new StringWriter();
515         out.write("<?xml version='1.0'?>");
516 
517         BeanWriter writer = new BeanWriter(out);
518         writer.setWriteEmptyElements(true);
519         writer.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(true);
520         writer.getBindingConfiguration().setMapIDs(false);
521         writer.write("CarryOn", names);
522         
523         String xml = "<?xml version='1.0'?><CarryOn><names>"
524          + "<name><name>Sid James</name></name>" 
525          + "<name><name>Kenneth Williams</name></name>" 
526          + "<name><name>Joan Simms</name></name>" 
527          + "<name><name>Charles Hawtrey</name></name>" 
528          + "</names>"
529          +"</CarryOn>";
530          
531         xmlAssertIsomorphicContent(
532                             parseString(out.getBuffer().toString()),
533                             parseString(xml), 
534                             true);
535                             
536         out = new StringWriter();
537         out.write("<?xml version='1.0'?>");
538 
539         writer = new BeanWriter(out);
540         writer.setWriteEmptyElements(true);
541         writer.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(true);
542         writer.getBindingConfiguration().setMapIDs(false);
543         writer.getXMLIntrospector().getConfiguration().setElementNameMapper(new CapitalizeNameMapper());
544         writer.write("CarryOn", names);
545         
546         xml = "<?xml version='1.0'?><CarryOn><Names>"
547          + "<Name><Name>Sid James</Name></Name>" 
548          + "<Name><Name>Kenneth Williams</Name></Name>" 
549          + "<Name><Name>Joan Simms</Name></Name>" 
550          + "<Name><Name>Charles Hawtrey</Name></Name>" 
551          + "</Names>"
552          +"</CarryOn>";
553          
554         xmlAssertIsomorphicContent(
555                             parseString(out.getBuffer().toString()),
556                             parseString(xml), 
557                             true);
558                             
559         ArrayList things = new ArrayList();
560         things.add(new NameBean("Sugar"));
561         things.add(new NameBean("Spice"));
562         things.add(new NameBean("All Things Nice"));
563         
564         NoAdderBean bean = new NoAdderBean();
565         bean.setThings(things);
566         
567         out = new StringWriter();
568         out.write("<?xml version='1.0'?>");
569         writer = new BeanWriter(out);
570         writer.setWriteEmptyElements(true);
571         writer.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(true);
572         writer.getBindingConfiguration().setMapIDs(false);
573         writer.write(bean);
574         
575         xml = "<?xml version='1.0'?><NoAdderBean><things>"
576          + "<NameBean><name>Sugar</name></NameBean>" 
577          + "<NameBean><name>Spice</name></NameBean>" 
578          + "<NameBean><name>All Things Nice</name></NameBean>" 
579          + "</things>"
580          +"</NoAdderBean>";
581          
582         xmlAssertIsomorphicContent(
583                             parseString(out.getBuffer().toString()),
584                             parseString(xml), 
585                             true);
586         
587         out = new StringWriter();
588         out.write("<?xml version='1.0'?>");
589         writer = new BeanWriter(out);
590         writer.setWriteEmptyElements(true);
591         writer.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(true);
592         writer.getBindingConfiguration().setMapIDs(false);
593         writer.getXMLIntrospector().getConfiguration().setElementNameMapper(new CapitalizeNameMapper());
594         writer.write(bean);
595         
596         xml = "<?xml version='1.0'?><NoAdderBean><Things>"
597          + "<NameBean><Name>Sugar</Name></NameBean>" 
598          + "<NameBean><Name>Spice</Name></NameBean>" 
599          + "<NameBean><Name>All Things Nice</Name></NameBean>" 
600          + "</Things>"
601          +"</NoAdderBean>";
602          
603         xmlAssertIsomorphicContent(
604                             parseString(out.getBuffer().toString()),
605                             parseString(xml), 
606                             true);
607                             
608         out = new StringWriter();
609         out.write("<?xml version='1.0'?>");
610         writer = new BeanWriter(out);
611         writer.setWriteEmptyElements(true);
612         writer.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(true);
613         writer.getBindingConfiguration().setMapIDs(false);
614         writer.getXMLIntrospector().getConfiguration().setElementNameMapper(new HyphenatedNameMapper(false));
615         writer.write(bean);
616         
617         xml = "<?xml version='1.0'?><no-adder-bean><things>"
618          + "<name-bean><name>Sugar</name></name-bean>" 
619          + "<name-bean><name>Spice</name></name-bean>" 
620          + "<name-bean><name>All Things Nice</name></name-bean>" 
621          + "</things>"
622          +"</no-adder-bean>";
623          
624         xmlAssertIsomorphicContent(
625                             parseString(out.getBuffer().toString()),
626                             parseString(xml), 
627                             true);
628     }
629     
630     public void testBeanWriterWorksWithAnAddMethodAndACollection() throws Exception {
631 
632         BeanWriter bw = new BeanWriter();
633         try {
634             bw.write(new BeanWithAddMethod());
635         } catch (IllegalArgumentException e) {
636             fail("BeanWriter fails when a method is just called add(<type>) and there is also a collection");
637         }
638     }
639     
640     // used in testBeanWriterWorksWithAnAddMethodAndACollection
641     public static class BeanWithAddMethod {
642         private Collection x;
643         public void add(Object x)
644         {
645             // do nothing
646         }
647 
648         public Collection getX() {
649             return x;
650         }
651 
652         public void setX(Collection x) {
653             this.x = x;
654         }        
655     }
656 }
657