001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.commons.betwixt.recursion;
019:
020: import java.io.StringReader;
021: import java.io.StringWriter;
022: import java.io.Writer;
023: import java.util.List;
024:
025: import junit.framework.Test;
026: import junit.framework.TestSuite;
027:
028: import org.apache.commons.betwixt.AbstractTestCase;
029: import org.apache.commons.betwixt.XMLIntrospector;
030: import org.apache.commons.betwixt.io.BeanReader;
031: import org.apache.commons.betwixt.io.BeanWriter;
032: import org.apache.commons.betwixt.io.CyclicReferenceException;
033:
034: /**
035: * This will test the recursive behaviour of betwixt.
036: *
037: * @author <a href="mailto:martin@mvdb.net">Martin van den Bemt </a>
038: * @version $Id: TestRecursion.java 438373 2006-08-30 05:17:21Z bayard $
039: */
040: public class TestRecursion extends AbstractTestCase {
041:
042: public TestRecursion(String testName) {
043: super (testName);
044: }
045:
046: public static Test suite() {
047: return new TestSuite(TestRecursion.class);
048: }
049:
050: /**
051: * This will test reading a simple recursive xml file
052: *
053: */
054: public void testReadwithCollectionsInElementRoundTrip()
055: throws Exception {
056: //SimpleLog log = new
057: // SimpleLog("[testReadwithCollectionsInElementRoundTrip:XMLIntrospectorHelper]");
058: //log.setLevel(SimpleLog.LOG_LEVEL_TRACE);
059: //XMLIntrospectorHelper.setLog(log);
060:
061: //log = new
062: // SimpleLog("[testReadwithCollectionsInElementRoundTrip:XMLIntrospector]");
063: //log.setLevel(SimpleLog.LOG_LEVEL_TRACE);
064:
065: XMLIntrospector intro = createXMLIntrospector();
066: //intro.setLog(log);
067: intro.getConfiguration().setWrapCollectionsInElement(true);
068:
069: //log = new
070: // SimpleLog("[testReadwithCollectionsInElementRoundTrip:BeanReader]");
071: //log.setLevel(SimpleLog.LOG_LEVEL_TRACE);
072:
073: BeanReader reader = new BeanReader();
074: reader.setXMLIntrospector(intro);
075: //reader.setLog(log);
076: reader.registerBeanClass(ElementBean.class);
077:
078: ElementBean bean = (ElementBean) reader
079: .parse(getTestFileURL("src/test/org/apache/commons/betwixt/recursion/recursion.xml"));
080:
081: List elements = bean.getElements();
082: assertEquals("Root elements size", 2, elements.size());
083: Element elementOne = (Element) elements.get(0);
084: assertEquals("Element one name", "element1", elementOne
085: .getName());
086: Element elementTwo = (Element) elements.get(1);
087: assertEquals("Element two name", "element2", elementTwo
088: .getName());
089: assertEquals("Element two children", 0, elementTwo
090: .getElements().size());
091: elements = elementOne.getElements();
092: assertEquals("Element one children", 2, elements.size());
093: Element elementOneOne = (Element) elements.get(0);
094: assertEquals("Element one one name", "element11", elementOneOne
095: .getName());
096: Element elementOneTwo = (Element) elements.get(1);
097: assertEquals("Element one two name", "element12", elementOneTwo
098: .getName());
099: assertEquals("Element one two children", 0, elementOneTwo
100: .getElements().size());
101: elements = elementOneOne.getElements();
102: assertEquals("Element one one children", 2, elements.size());
103: Element elementOneOneOne = (Element) elements.get(0);
104: assertEquals("Element one one one name", "element111",
105: elementOneOneOne.getName());
106: Element elementOneOneTwo = (Element) elements.get(1);
107: assertEquals("Element one one two name", "element112",
108: elementOneOneTwo.getName());
109:
110: StringWriter buffer = new StringWriter();
111: write(bean, buffer, true);
112:
113: String xml = "<?xml version='1.0'?><ElementBean><elements><element name='element1'>"
114: + "<elements><element name='element11'><elements><element name='element111'>"
115: + "<elements/></element><element name='element112'><elements/></element>"
116: + "</elements></element><element name='element12'><elements/></element>"
117: + "</elements></element><element name='element2'><elements/>"
118: + "</element></elements></ElementBean>";
119:
120: xmlAssertIsomorphic(parseString(xml), parseString(buffer
121: .getBuffer().toString()), true);
122: }
123:
124: /**
125: * This will test reading a simple recursive xml file
126: */
127: public void testReadWithoutCollectionsInElementRoundTrip()
128: throws Exception {
129: // SimpleLog log = new
130: // SimpleLog("[testReadWithoutCollectionsInElementRoundTrip:BeanRuleSet]");
131: // log.setLevel(SimpleLog.LOG_LEVEL_TRACE);
132: // BeanRuleSet.setLog(log);
133:
134: // log = new
135: // SimpleLog("[testReadWithoutCollectionsInElementRoundTrip:XMLIntrospector]");
136: // log.setLevel(SimpleLog.LOG_LEVEL_TRACE);
137:
138: XMLIntrospector intro = createXMLIntrospector();
139: intro.getConfiguration().setWrapCollectionsInElement(false);
140: // intro.setLog(log);
141: // log = new
142: // SimpleLog("[testReadWithoutCollectionsInElementRoundTrip:XMLIntrospectorHelper]");
143: // log.setLevel(SimpleLog.LOG_LEVEL_TRACE);
144: // XMLIntrospectorHelper.setLog(log);
145: BeanReader reader = new BeanReader();
146: // log = new
147: // SimpleLog("[testReadWithoutCollectionsInElementRoundTrip:BeanReader]");
148: // log.setLevel(SimpleLog.LOG_LEVEL_TRACE);
149: // reader.setLog(log);
150: reader.setXMLIntrospector(intro);
151: reader.registerBeanClass(ElementBean.class);
152: ElementBean bean = (ElementBean) reader
153: .parse(getTestFileURL("src/test/org/apache/commons/betwixt/recursion/recursion2.xml"));
154: List elements = bean.getElements();
155: assertEquals("Number of elements in root bean", 2, elements
156: .size());
157: Element elementOne = (Element) bean.elements.get(0);
158: assertEquals("First element name", "element1", elementOne
159: .getName());
160: Element elementTwo = (Element) bean.elements.get(1);
161: assertEquals("Second element name", "element2", elementTwo
162: .getName());
163:
164: elements = elementOne.getElements();
165: assertEquals("Number of child elements in first element", 2,
166: elements.size());
167: Element elementOneOne = (Element) elements.get(0);
168: assertEquals("11 element name", "element11", elementOneOne
169: .getName());
170: Element elementOneTwo = (Element) elements.get(1);
171: assertEquals("12 element name", "element12", elementOneTwo
172: .getName());
173:
174: elements = elementOneOne.getElements();
175: assertEquals("Number of child elements in element 11", 2,
176: elements.size());
177: Element elementOneOneOne = (Element) elements.get(0);
178: assertEquals("111 element name", "element111", elementOneOneOne
179: .getName());
180:
181: assertEquals("111 child elements ", 0, elementOneOneOne
182: .getElements().size());
183:
184: Element elementOneOneTwo = (Element) elements.get(1);
185: assertEquals("112 element name", "element112", elementOneOneTwo
186: .getName());
187: assertEquals("112 child elements ", 0, elementOneOneTwo
188: .getElements().size());
189:
190: elements = elementOneTwo.getElements();
191: assertEquals("Number of child elements in element 12", 0,
192: elements.size());
193:
194: elements = elementTwo.getElements();
195: assertEquals("Number of child elements in element 2", 0,
196: elements.size());
197:
198: StringWriter buffer = new StringWriter();
199: buffer.write("<?xml version='1.0'?>");
200: write(bean, buffer, false);
201:
202: String xml = "<ElementBean><element name='element1'><element name='element11'><element name='element111' />"
203: + "<element name='element112' /> </element><element name='element12' /> </element>"
204: + "<element name='element2' /> </ElementBean>";
205:
206: xmlAssertIsomorphic(parseString(xml), parseString(buffer
207: .getBuffer().toString()), true);
208:
209: }
210:
211: /**
212: * Opens a writer and writes an object model according to the retrieved bean
213: */
214: private void write(Object bean, Writer out, boolean wrapIt)
215: throws Exception {
216: BeanWriter writer = new BeanWriter(out);
217: writer.setWriteEmptyElements(true);
218: writer.setXMLIntrospector(createXMLIntrospector());
219: // specifies weather to use collection elements or not.
220: writer.getXMLIntrospector().getConfiguration()
221: .setWrapCollectionsInElement(wrapIt);
222: // we don't want to write Id attributes to every element
223: // we just want our opbject model written nothing more..
224: writer.getBindingConfiguration().setMapIDs(false);
225: // the source has 2 spaces indention and \n as line seperator.
226: writer.setIndent(" ");
227: writer.setEndOfLine("\n");
228: writer.write(bean);
229: }
230:
231: /**
232: * Set up the XMLIntroSpector
233: */
234: protected XMLIntrospector createXMLIntrospector() {
235: XMLIntrospector introspector = new XMLIntrospector();
236:
237: // set elements for attributes to true
238: introspector.getConfiguration()
239: .setAttributesForPrimitives(true);
240: introspector.getConfiguration().setWrapCollectionsInElement(
241: false);
242:
243: return introspector;
244: }
245:
246: /**
247: */
248: public void testBeanWithIdProperty() throws Exception {
249: IdBean bean = new IdBean("Hello, World");
250: bean.setNotId("Not ID");
251: StringWriter out = new StringWriter();
252: out.write("<?xml version='1.0'?>");
253: BeanWriter writer = new BeanWriter(out);
254: writer.setWriteEmptyElements(true);
255: writer.getXMLIntrospector().getConfiguration()
256: .setAttributesForPrimitives(true);
257: writer.getBindingConfiguration().setMapIDs(true);
258: writer.write(bean);
259:
260: String xml = "<?xml version='1.0'?><IdBean notId='Not ID' id='Hello, World'/>";
261:
262: xmlAssertIsomorphic(parseString(xml), parseString(out
263: .getBuffer().toString()), true);
264: }
265:
266: /**
267: * Check that a cyclic reference exception is not thrown in this case
268: */
269: public void testCyclicReferenceStack1() throws Exception {
270: Element alpha = new Element("Alpha");
271: Element beta = new Element("Beta");
272: Element gamma = new Element("Gamma");
273: Element epsilon = new Element("Epsilon");
274:
275: alpha.addElement(beta);
276: beta.addElement(gamma);
277: gamma.addElement(epsilon);
278: alpha.addElement(epsilon);
279:
280: StringWriter stringWriter = new StringWriter();
281: BeanWriter writer = new BeanWriter(stringWriter);
282: writer.setWriteEmptyElements(true);
283: writer.getBindingConfiguration().setMapIDs(false);
284: writer.write(alpha);
285:
286: String xml = "<?xml version='1.0'?><Element><name>Alpha</name><elements><element>"
287: + "<name>Beta</name><elements><element><name>Gamma</name><elements>"
288: + "<element><name>Epsilon</name><elements/></element></elements>"
289: + "</element></elements></element><element><name>Epsilon</name>"
290: + "<elements/></element></elements></Element>";
291:
292: xmlAssertIsomorphic(parseString(xml), parseString(stringWriter
293: .getBuffer().toString()), true);
294: }
295:
296: /**
297: * This should throw a cyclic reference
298: */
299: public void testCyclicReferenceStack2() throws Exception {
300: Element alpha = new Element("Alpha");
301: Element beta = new Element("Beta");
302: Element gamma = new Element("Gamma");
303: Element epsilon = new Element("Epsilon");
304:
305: alpha.addElement(beta);
306: beta.addElement(gamma);
307: gamma.addElement(epsilon);
308: epsilon.addElement(beta);
309:
310: StringWriter stringWriter = new StringWriter();
311: BeanWriter writer = new BeanWriter(stringWriter);
312: writer.setWriteEmptyElements(true);
313: writer.getBindingConfiguration().setMapIDs(false);
314:
315: //SimpleLog log = new
316: // SimpleLog("[testCyclicReferenceStack2:BeanWriter]");
317: //log.setLevel(SimpleLog.LOG_LEVEL_TRACE);
318: //writer.setLog(log);
319:
320: //log = new SimpleLog("[testCyclicReferenceStack2:BeanWriter]");
321: //log.setLevel(SimpleLog.LOG_LEVEL_TRACE);
322: //writer.setAbstractBeanWriterLog(log);
323:
324: try {
325: writer.write(alpha);
326: fail("Cycle was not detected!");
327:
328: } catch (CyclicReferenceException e) {
329: // that's what we expected!
330: }
331: }
332:
333: /** Tests for a stack overflow bug */
334: public void testRegisterOverflow() throws Exception {
335: BeanReader reader = new BeanReader();
336: try {
337: reader.registerBeanClass(NorthWind.class);
338: } catch (StackOverflowError e) {
339: e.printStackTrace();
340: fail("Expected registration to succeed");
341: }
342: }
343:
344: public void testRegisterOverflow2() throws Exception {
345: BeanReader beanReader = new BeanReader();
346: try {
347: beanReader.registerBeanClass(PersonTest.class);
348: } catch (StackOverflowError e) {
349: e.printStackTrace();
350: fail("Expected registration to succeed");
351: }
352: }
353:
354: public void testCycleReferences() throws Exception {
355: PersonTest person = new PersonTest();
356: person.setName("John Doe");
357: AddressTest address = new AddressTest();
358: address.setStreetAddress("1221 Washington Street");
359: person.setAddress(address);
360: ReferenceTest reference = new ReferenceTest();
361: reference.setPerson(person);
362: address.setReference(reference);
363:
364: StringWriter outputWriter = new StringWriter();
365:
366: outputWriter.write("<?xml version='1.0' ?>\n");
367: BeanWriter beanWriter = new BeanWriter(outputWriter);
368: beanWriter.setEndOfLine("\n");
369: beanWriter.enablePrettyPrint();
370: beanWriter.getBindingConfiguration().setMapIDs(true);
371: beanWriter.write(person);
372:
373: BeanReader beanReader = new BeanReader();
374: beanReader.getBindingConfiguration().setMapIDs(true);
375:
376: // Configure the reader
377: beanReader.registerBeanClass(PersonTest.class);
378: beanReader.registerBeanClass(AddressTest.class);
379: beanReader.registerBeanClass(ReferenceTest.class);
380:
381: String out = outputWriter.toString();
382: StringReader xmlReader = new StringReader(out);
383:
384: //Parse the xml
385: PersonTest result = (PersonTest) beanReader.parse(xmlReader);
386: assertSame("Cycle did not result in the same reference",
387: result, result.getAddress().getReference().getPerson());
388:
389: }
390:
391: }
|