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