1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.betwixt.recursion;
18
19 import java.io.StringReader;
20 import java.io.StringWriter;
21 import java.io.Writer;
22 import java.util.List;
23
24 import junit.framework.Test;
25 import junit.framework.TestSuite;
26
27 import org.apache.commons.betwixt.AbstractTestCase;
28 import org.apache.commons.betwixt.XMLIntrospector;
29 import org.apache.commons.betwixt.io.BeanReader;
30 import org.apache.commons.betwixt.io.BeanWriter;
31 import org.apache.commons.betwixt.io.CyclicReferenceException;
32
33
34 /***
35 * This will test the recursive behaviour of betwixt.
36 *
37 * @author <a href="mailto:martin@mvdb.net">Martin van den Bemt</a>
38 * @version $Id: TestRecursion.java,v 1.15 2004/06/13 21:32:48 rdonkin Exp $
39 */
40 public class TestRecursion extends AbstractTestCase
41 {
42
43
44
45 public TestRecursion(String testName)
46 {
47 super(testName);
48 }
49
50 public static Test suite()
51 {
52 return new TestSuite(TestRecursion.class);
53 }
54
55 /***
56 * This will test reading a simple recursive xml file
57 *
58 */
59 public void testReadwithCollectionsInElementRoundTrip()
60 throws Exception
61 {
62
63
64
65
66
67
68
69 XMLIntrospector intro = createXMLIntrospector();
70
71 intro.getConfiguration().setWrapCollectionsInElement(true);
72
73
74
75
76 BeanReader reader = new BeanReader();
77 reader.setXMLIntrospector(intro);
78
79 reader.registerBeanClass(ElementBean.class);
80
81 ElementBean bean = (ElementBean) reader.parse(
82 getTestFileURL("src/test/org/apache/commons/betwixt/recursion/recursion.xml"));
83
84 List elements = bean.getElements();
85 assertEquals("Root elements size", 2, elements.size());
86 Element elementOne = (Element) elements.get(0);
87 assertEquals("Element one name", "element1", elementOne.getName());
88 Element elementTwo = (Element) elements.get(1);
89 assertEquals("Element two name", "element2", elementTwo.getName());
90 assertEquals("Element two children", 0, elementTwo.getElements().size());
91 elements = elementOne.getElements();
92 assertEquals("Element one children", 2, elements.size());
93 Element elementOneOne = (Element) elements.get(0);
94 assertEquals("Element one one name", "element11", elementOneOne.getName());
95 Element elementOneTwo = (Element) elements.get(1);
96 assertEquals("Element one two name", "element12", elementOneTwo.getName());
97 assertEquals("Element one two children", 0, elementOneTwo.getElements().size());
98 elements = elementOneOne.getElements();
99 assertEquals("Element one one children", 2, elements.size());
100 Element elementOneOneOne = (Element) elements.get(0);
101 assertEquals("Element one one one name", "element111", elementOneOneOne.getName());
102 Element elementOneOneTwo = (Element) elements.get(1);
103 assertEquals("Element one one two name", "element112", elementOneOneTwo.getName());
104
105 StringWriter buffer = new StringWriter();
106 write (bean, buffer, true);
107
108 String xml = "<?xml version='1.0'?><ElementBean><elements><element name='element1'>"
109 + "<elements><element name='element11'><elements><element name='element111'>"
110 + "<elements/></element><element name='element112'><elements/></element>"
111 + "</elements></element><element name='element12'><elements/></element>"
112 + "</elements></element><element name='element2'><elements/>"
113 + "</element></elements></ElementBean>";
114
115 xmlAssertIsomorphic(
116 parseString(xml),
117 parseString(buffer.getBuffer().toString()),
118 true);
119 }
120 /***
121 * This will test reading a simple recursive xml file
122 */
123 public void testReadWithoutCollectionsInElementRoundTrip()
124 throws Exception
125 {
126
127
128
129
130
131
132
133 XMLIntrospector intro = createXMLIntrospector();
134 intro.getConfiguration().setWrapCollectionsInElement(false);
135
136
137
138
139 BeanReader reader = new BeanReader();
140
141
142
143 reader.setXMLIntrospector(intro);
144 reader.registerBeanClass(ElementBean.class);
145 ElementBean bean = (ElementBean) reader.
146 parse(getTestFileURL("src/test/org/apache/commons/betwixt/recursion/recursion2.xml"));
147 List elements = bean.getElements();
148 assertEquals("Number of elements in root bean", 2, elements.size());
149 Element elementOne = (Element) bean.elements.get(0);
150 assertEquals("First element name", "element1", elementOne.getName());
151 Element elementTwo = (Element) bean.elements.get(1);
152 assertEquals("Second element name", "element2", elementTwo.getName());
153
154 elements = elementOne.getElements();
155 assertEquals("Number of child elements in first element", 2, elements.size());
156 Element elementOneOne = (Element) elements.get(0);
157 assertEquals("11 element name", "element11", elementOneOne.getName());
158 Element elementOneTwo = (Element) elements.get(1);
159 assertEquals("12 element name", "element12", elementOneTwo.getName());
160
161 elements = elementOneOne.getElements();
162 assertEquals("Number of child elements in element 11", 2, elements.size());
163 Element elementOneOneOne = (Element) elements.get(0);
164 assertEquals("111 element name", "element111", elementOneOneOne.getName());
165
166 assertEquals("111 child elements ", 0, elementOneOneOne.getElements().size());
167
168 Element elementOneOneTwo = (Element) elements.get(1);
169 assertEquals("112 element name", "element112", elementOneOneTwo.getName());
170 assertEquals("112 child elements ", 0, elementOneOneTwo.getElements().size());
171
172 elements = elementOneTwo.getElements();
173 assertEquals("Number of child elements in element 12", 0, elements.size());
174
175 elements = elementTwo.getElements();
176 assertEquals("Number of child elements in element 2", 0, elements.size());
177
178 StringWriter buffer = new StringWriter();
179 buffer.write("<?xml version='1.0'?>");
180 write (bean, buffer, false);
181
182 String xml = "<ElementBean><element name='element1'><element name='element11'><element name='element111' />"
183 + "<element name='element112' /> </element><element name='element12' /> </element>"
184 + "<element name='element2' /> </ElementBean>";
185
186 xmlAssertIsomorphic(parseString(xml), parseString(buffer.getBuffer().toString()), true);
187
188 }
189
190 /***
191 * Opens a writer and writes an object model according to the
192 * retrieved bean
193 */
194 private void write(Object bean, Writer out, boolean wrapIt)
195 throws Exception
196 {
197 BeanWriter writer = new BeanWriter(out);
198 writer.setWriteEmptyElements( true );
199 writer.setXMLIntrospector(createXMLIntrospector());
200
201 writer.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(wrapIt);
202
203
204 writer.getBindingConfiguration().setMapIDs(false);
205
206 writer.setIndent(" ");
207 writer.setEndOfLine("\n");
208 writer.write(bean);
209 }
210 /***
211 * Set up the XMLIntroSpector
212 */
213 protected XMLIntrospector createXMLIntrospector() {
214 XMLIntrospector introspector = new XMLIntrospector();
215
216
217 introspector.getConfiguration().setAttributesForPrimitives(true);
218 introspector.getConfiguration().setWrapCollectionsInElement(false);
219
220 return introspector;
221 }
222
223
224 /***
225 */
226 public void testBeanWithIdProperty() throws Exception
227 {
228 IdBean bean = new IdBean("Hello, World");
229 bean.setNotId("Not ID");
230 StringWriter out = new StringWriter();
231 out.write("<?xml version='1.0'?>");
232 BeanWriter writer = new BeanWriter(out);
233 writer.setWriteEmptyElements( true );
234 writer.getXMLIntrospector().getConfiguration().setAttributesForPrimitives(true);
235 writer.getBindingConfiguration().setMapIDs(true);
236 writer.write(bean);
237
238 String xml = "<?xml version='1.0'?><IdBean notId='Not ID' id='Hello, World'/>";
239
240 xmlAssertIsomorphic(parseString(xml), parseString(out.getBuffer().toString()), true);
241 }
242
243 /***
244 * Check that a cyclic reference exception is not thrown in this case
245 */
246 public void testCyclicReferenceStack1() throws Exception
247 {
248 Element alpha = new Element("Alpha");
249 Element beta = new Element("Beta");
250 Element gamma = new Element("Gamma");
251 Element epsilon = new Element("Epsilon");
252
253 alpha.addElement(beta);
254 beta.addElement(gamma);
255 gamma.addElement(epsilon);
256 alpha.addElement(epsilon);
257
258 StringWriter stringWriter = new StringWriter();
259 BeanWriter writer = new BeanWriter(stringWriter);
260 writer.setWriteEmptyElements( true );
261 writer.getBindingConfiguration().setMapIDs(false);
262 writer.write(alpha);
263
264 String xml = "<?xml version='1.0'?><Element><name>Alpha</name><elements><element>"
265 + "<name>Beta</name><elements><element><name>Gamma</name><elements>"
266 + "<element><name>Epsilon</name><elements/></element></elements>"
267 + "</element></elements></element><element><name>Epsilon</name>"
268 + "<elements/></element></elements></Element>";
269
270 xmlAssertIsomorphic(parseString(xml), parseString(stringWriter.getBuffer().toString()), true);
271 }
272
273 /***
274 * This should throw a cyclic reference
275 */
276 public void testCyclicReferenceStack2() throws Exception
277 {
278 Element alpha = new Element("Alpha");
279 Element beta = new Element("Beta");
280 Element gamma = new Element("Gamma");
281 Element epsilon = new Element("Epsilon");
282
283 alpha.addElement(beta);
284 beta.addElement(gamma);
285 gamma.addElement(epsilon);
286 epsilon.addElement(beta);
287
288 StringWriter stringWriter = new StringWriter();
289 BeanWriter writer = new BeanWriter(stringWriter);
290 writer.setWriteEmptyElements( true );
291 writer.getBindingConfiguration().setMapIDs(false);
292
293
294
295
296
297
298
299
300
301 try {
302 writer.write(alpha);
303 fail("Cycle was not detected!");
304
305 } catch (CyclicReferenceException e) {
306
307 }
308 }
309
310
311 /*** Tests for a stack overflow bug */
312 public void testRegisterOverflow() throws Exception {
313 BeanReader reader = new BeanReader();
314 try
315 {
316 reader.registerBeanClass(NorthWind.class);
317 }
318 catch (StackOverflowError e)
319 {
320 e.printStackTrace();
321 fail("Expected registration to succeed");
322 }
323 }
324
325 public void testRegisterOverflow2() throws Exception {
326 BeanReader beanReader = new BeanReader();
327 try
328 {
329 beanReader.registerBeanClass(PersonTest.class);
330 }
331 catch (StackOverflowError e)
332 {
333 e.printStackTrace();
334 fail("Expected registration to succeed");
335 }
336 }
337
338 public void testCycleReferences() throws Exception {
339 PersonTest person = new PersonTest();
340 person.setName("John Doe");
341 AddressTest address = new AddressTest();
342 address.setStreetAddress("1221 Washington Street");
343 person.setAddress(address);
344 ReferenceTest reference = new ReferenceTest();
345 reference.setPerson(person);
346 address.setReference(reference);
347
348 StringWriter outputWriter = new StringWriter();
349
350 outputWriter.write("<?xml version='1.0' ?>\n");
351 BeanWriter beanWriter = new BeanWriter(outputWriter);
352 beanWriter.enablePrettyPrint();
353 beanWriter.getBindingConfiguration().setMapIDs(true);
354 beanWriter.write(person);
355
356 BeanReader beanReader = new BeanReader();
357 beanReader.getBindingConfiguration().setMapIDs(true);
358
359
360 beanReader.registerBeanClass(PersonTest.class);
361 beanReader.registerBeanClass(AddressTest.class);
362 beanReader.registerBeanClass(ReferenceTest.class);
363
364 String out = outputWriter.toString();
365 StringReader xmlReader = new StringReader(out);
366
367
368 PersonTest result = (PersonTest)beanReader.parse(xmlReader);
369 assertSame("Cycle did not result in the same reference", result, result.getAddress().getReference().getPerson());
370
371 }
372
373
374 }
375