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