http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/75b0d8ee/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/BasicXmlTest.java ---------------------------------------------------------------------- diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/BasicXmlTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/BasicXmlTest.java new file mode 100644 index 0000000..8ca9c37 --- /dev/null +++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/BasicXmlTest.java @@ -0,0 +1,1702 @@ +// *************************************************************************************************************************** +// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * +// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * +// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * +// * with the License. You may obtain a copy of the License at * +// * * +// * http://www.apache.org/licenses/LICENSE-2.0 * +// * * +// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * +// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * +// * specific language governing permissions and limitations under the License. * +// *************************************************************************************************************************** +package org.apache.juneau.xml; + +import static org.junit.Assert.*; + +import java.util.*; + +import org.apache.juneau.*; +import org.apache.juneau.annotation.*; +import org.apache.juneau.xml.annotation.*; +import org.junit.*; +import org.junit.runner.*; +import org.junit.runners.*; + +@RunWith(Parameterized.class) +@SuppressWarnings({"javadoc","serial"}) +public class BasicXmlTest { + + private static final XmlSerializer + s1 = XmlSerializer.DEFAULT_SQ, + s2 = XmlSerializer.DEFAULT_SQ_READABLE, + s3 = XmlSerializer.DEFAULT_NS_SQ; + private static final XmlParser parser = XmlParser.DEFAULT; + + @Parameterized.Parameters + public static Collection<Object[]> getParameters() { + return Arrays.asList(new Object[][] { + + { + "SimpleTypes-1", + "foo", + "<string>foo</string>", + "<string>foo</string>\n", + "<string>foo</string>", + }, + { + "SimpleTypes-2", + true, + "<boolean>true</boolean>", + "<boolean>true</boolean>\n", + "<boolean>true</boolean>", + }, + { + "SimpleTypes-3", + 123, + "<number>123</number>", + "<number>123</number>\n", + "<number>123</number>", + }, + { + "SimpleTypes-4", + 1.23f, + "<number>1.23</number>", + "<number>1.23</number>\n", + "<number>1.23</number>", + }, + { + "SimpleTypes-5", + null, + "<null/>", + "<null/>\n", + "<null/>", + }, + { + "Arrays-1", + new String[]{"foo"}, + "<array><string>foo</string></array>", + "<array>\n\t<string>foo</string>\n</array>\n", + "<array><string>foo</string></array>", + }, + { + "Arrays-2", + new String[]{null}, + "<array><null/></array>", + "<array>\n\t<null/>\n</array>\n", + "<array><null/></array>", + }, + { + "Arrays-3", + new Object[]{"foo"}, + "<array><string>foo</string></array>", + "<array>\n\t<string>foo</string>\n</array>\n", + "<array><string>foo</string></array>", + }, + { + "Arrays-4", + new int[]{123}, + "<array><number>123</number></array>", + "<array>\n\t<number>123</number>\n</array>\n", + "<array><number>123</number></array>", + }, + { + "Arrays-5", + new boolean[]{true}, + "<array><boolean>true</boolean></array>", + "<array>\n\t<boolean>true</boolean>\n</array>\n", + "<array><boolean>true</boolean></array>", + }, + { + "Arrays-6", + new String[][]{{"foo"}}, + "<array><array><string>foo</string></array></array>", + "<array>\n\t<array>\n\t\t<string>foo</string>\n\t</array>\n</array>\n", + "<array><array><string>foo</string></array></array>", + }, + { + "MapWithStrings", + new MapWithStrings().append("k1", "v1").append("k2", null), + "<object><k1>v1</k1><k2 _type='null'/></object>", + "<object>\n\t<k1>v1</k1>\n\t<k2 _type='null'/>\n</object>\n", + "<object><k1>v1</k1><k2 _type='null'/></object>", + }, + { + "MapsWithNumbers", + new MapWithNumbers().append("k1", 123).append("k2", 1.23).append("k3", null), + "<object><k1>123</k1><k2>1.23</k2><k3 _type='null'/></object>", + "<object>\n\t<k1>123</k1>\n\t<k2>1.23</k2>\n\t<k3 _type='null'/>\n</object>\n", + "<object><k1>123</k1><k2>1.23</k2><k3 _type='null'/></object>", + }, + { + "MapWithObjects", + new MapWithObjects().append("k1", "v1").append("k2", 123).append("k3", 1.23).append("k4", true).append("k5", null), + "<object><k1>v1</k1><k2 _type='number'>123</k2><k3 _type='number'>1.23</k3><k4 _type='boolean'>true</k4><k5 _type='null'/></object>", + "<object>\n\t<k1>v1</k1>\n\t<k2 _type='number'>123</k2>\n\t<k3 _type='number'>1.23</k3>\n\t<k4 _type='boolean'>true</k4>\n\t<k5 _type='null'/>\n</object>\n", + "<object><k1>v1</k1><k2 _type='number'>123</k2><k3 _type='number'>1.23</k3><k4 _type='boolean'>true</k4><k5 _type='null'/></object>", + }, + { + "ListWithStrings", + new ListWithStrings().append("foo").append(null), + "<array><string>foo</string><null/></array>", + "<array>\n\t<string>foo</string>\n\t<null/>\n</array>\n", + "<array><string>foo</string><null/></array>", + }, + { + "ListWithNumbers", + new ListWithNumbers().append(123).append(1.23).append(null), + "<array><number>123</number><number>1.23</number><null/></array>", + "<array>\n\t<number>123</number>\n\t<number>1.23</number>\n\t<null/>\n</array>\n", + "<array><number>123</number><number>1.23</number><null/></array>", + }, + { + "ListWithObjects", + new ListWithObjects().append("foo").append(123).append(1.23).append(true).append(null), + "<array><string>foo</string><number>123</number><number>1.23</number><boolean>true</boolean><null/></array>", + "<array>\n\t<string>foo</string>\n\t<number>123</number>\n\t<number>1.23</number>\n\t<boolean>true</boolean>\n\t<null/>\n</array>\n", + "<array><string>foo</string><number>123</number><number>1.23</number><boolean>true</boolean><null/></array>", + }, + { + "BeanWithNormalProperties", + new BeanWithNormalProperties().init(), + "<object>" + +"<a>foo</a>" + +"<b>123</b>" + +"<c>bar</c>" + +"<d _type='number'>456</d>" + +"<e>" + +"<h>qux</h>" + +"</e>" + +"<f>" + +"<string>baz</string>" + +"</f>" + +"<g>" + +"<number>789</number>" + +"</g>" + +"</object>", + "<object>" + +"\n\t<a>foo</a>" + +"\n\t<b>123</b>" + +"\n\t<c>bar</c>" + +"\n\t<d _type='number'>456</d>" + +"\n\t<e>" + +"\n\t\t<h>qux</h>" + +"\n\t</e>" + +"\n\t<f>" + +"\n\t\t<string>baz</string>" + +"\n\t</f>" + +"\n\t<g>" + +"\n\t\t<number>789</number>" + +"\n\t</g>" + +"\n</object>\n", + "<object>" + +"<a>foo</a>" + +"<b>123</b>" + +"<c>bar</c>" + +"<d _type='number'>456</d>" + +"<e>" + +"<h>qux</h>" + +"</e>" + +"<f>" + +"<string>baz</string>" + +"</f>" + +"<g>" + +"<number>789</number>" + +"</g>" + +"</object>", + }, + { + "BeanWithMapProperties", + new BeanWithMapProperties().init(), + "<object>" + +"<a>" + +"<k1>foo</k1>" + +"</a>" + +"<b>" + +"<k2>123</k2>" + +"</b>" + +"<c>" + +"<k3>bar</k3>" + +"<k4 _type='number'>456</k4>" + +"<k5 _type='boolean'>true</k5>" + +"<k6 _type='null'/>" + +"</c>" + +"</object>", + "<object>" + +"\n\t<a>" + +"\n\t\t<k1>foo</k1>" + +"\n\t</a>" + +"\n\t<b>" + +"\n\t\t<k2>123</k2>" + +"\n\t</b>" + +"\n\t<c>" + +"\n\t\t<k3>bar</k3>" + +"\n\t\t<k4 _type='number'>456</k4>" + +"\n\t\t<k5 _type='boolean'>true</k5>" + +"\n\t\t<k6 _type='null'/>" + +"\n\t</c>" + +"\n</object>\n", + "<object>" + +"<a>" + +"<k1>foo</k1>" + +"</a>" + +"<b>" + +"<k2>123</k2>" + +"</b>" + +"<c>" + +"<k3>bar</k3>" + +"<k4 _type='number'>456</k4>" + +"<k5 _type='boolean'>true</k5>" + +"<k6 _type='null'/>" + +"</c>" + +"</object>", + }, + { + "BeanWithTypeName", + new BeanWithTypeName().init(), + "<X><a>123</a><b>foo</b></X>", + "<X>\n\t<a>123</a>\n\t<b>foo</b>\n</X>\n", + "<X><a>123</a><b>foo</b></X>", + }, + { + "BeanWithPropertiesWithTypeNames", + new BeanWithPropertiesWithTypeNames().init(), + "<object><b1><b>foo</b></b1><b2 _type='B'><b>foo</b></b2></object>", + "<object>\n\t<b1>\n\t\t<b>foo</b>\n\t</b1>\n\t<b2 _type='B'>\n\t\t<b>foo</b>\n\t</b2>\n</object>\n", + "<object><b1><b>foo</b></b1><b2 _type='B'><b>foo</b></b2></object>" + }, + { + "BeanWithPropertiesWithArrayTypeNames", + new BeanWithPropertiesWithArrayTypeNames().init(), + "<object>" + +"<b1>" + +"<B>" + +"<b>foo</b>" + +"</B>" + +"</b1>" + +"<b2>" + +"<B>" + +"<b>foo</b>" + +"</B>" + +"</b2>" + +"<b3>" + +"<B>" + +"<b>foo</b>" + +"</B>" + +"</b3>" + +"</object>", + "<object>\n" + +"\t<b1>\n" + +"\t\t<B>\n" + +"\t\t\t<b>foo</b>\n" + +"\t\t</B>\n" + +"\t</b1>\n" + +"\t<b2>\n" + +"\t\t<B>\n" + +"\t\t\t<b>foo</b>\n" + +"\t\t</B>\n" + +"\t</b2>\n" + +"\t<b3>\n" + +"\t\t<B>\n" + +"\t\t\t<b>foo</b>\n" + +"\t\t</B>\n" + +"\t</b3>\n" + +"</object>\n", + "<object>" + +"<b1>" + +"<B>" + +"<b>foo</b>" + +"</B>" + +"</b1>" + +"<b2>" + +"<B>" + +"<b>foo</b>" + +"</B>" + +"</b2>" + +"<b3>" + +"<B>" + +"<b>foo</b>" + +"</B>" + +"</b3>" + +"</object>", + }, + { + "BeanWithPropertiesWithArray2dTypeNames", + new BeanWithPropertiesWith2dArrayTypeNames().init(), + "<object>" + +"<b1>" + +"<array>" + +"<B>" + +"<b>foo</b>" + +"</B>" + +"</array>" + +"</b1>" + +"<b2>" + +"<array>" + +"<B>" + +"<b>foo</b>" + +"</B>" + +"</array>" + +"</b2>" + +"<b3>" + +"<array>" + +"<B>" + +"<b>foo</b>" + +"</B>" + +"</array>" + +"</b3>" + +"</object>", + "<object>\n" + +"\t<b1>\n" + +"\t\t<array>\n" + +"\t\t\t<B>\n" + +"\t\t\t\t<b>foo</b>\n" + +"\t\t\t</B>\n" + +"\t\t</array>\n" + +"\t</b1>\n" + +"\t<b2>\n" + +"\t\t<array>\n" + +"\t\t\t<B>\n" + +"\t\t\t\t<b>foo</b>\n" + +"\t\t\t</B>\n" + +"\t\t</array>\n" + +"\t</b2>\n" + +"\t<b3>\n" + +"\t\t<array>\n" + +"\t\t\t<B>\n" + +"\t\t\t\t<b>foo</b>\n" + +"\t\t\t</B>\n" + +"\t\t</array>\n" + +"\t</b3>\n" + +"</object>\n", + "<object>" + +"<b1>" + +"<array>" + +"<B>" + +"<b>foo</b>" + +"</B>" + +"</array>" + +"</b1>" + +"<b2>" + +"<array>" + +"<B>" + +"<b>foo</b>" + +"</B>" + +"</array>" + +"</b2>" + +"<b3>" + +"<array>" + +"<B>" + +"<b>foo</b>" + +"</B>" + +"</array>" + +"</b3>" + +"</object>", + }, + { + "BeanWithPropertiesWithMapTypeNames", + new BeanWithPropertiesWithMapTypeNames().init(), + "<object>" + +"<b1>" + +"<k1>" + +"<b>foo</b>" + +"</k1>" + +"</b1>" + +"<b2>" + +"<k2 _type='B'>" + +"<b>foo</b>" + +"</k2>" + +"</b2>" + +"</object>", + "<object>\n" + +"\t<b1>\n" + +"\t\t<k1>\n" + +"\t\t\t<b>foo</b>\n" + +"\t\t</k1>\n" + +"\t</b1>\n" + +"\t<b2>\n" + +"\t\t<k2 _type='B'>\n" + +"\t\t\t<b>foo</b>\n" + +"\t\t</k2>\n" + +"\t</b2>\n" + +"</object>\n", + "<object>" + +"<b1>" + +"<k1>" + +"<b>foo</b>" + +"</k1>" + +"</b1>" + +"<b2>" + +"<k2 _type='B'>" + +"<b>foo</b>" + +"</k2>" + +"</b2>" + +"</object>", + }, + { + "BeanWithChildTypeNames", + new BeanWithChildTypeNames().init(), + "<object>" + +"<a>" + +"<fx>fx1</fx>" + +"</a>" + +"<b _type='X'>" + +"<fx>fx1</fx>" + +"</b>" + +"<c>" + +"<X>" + +"<fx>fx1</fx>" + +"</X>" + +"</c>" + +"<d>" + +"<X>" + +"<fx>fx1</fx>" + +"</X>" + +"</d>" + +"</object>", + "<object>" + +"\n\t<a>" + +"\n\t\t<fx>fx1</fx>" + +"\n\t</a>" + +"\n\t<b _type='X'>" + +"\n\t\t<fx>fx1</fx>" + +"\n\t</b>" + +"\n\t<c>" + +"\n\t\t<X>" + +"\n\t\t\t<fx>fx1</fx>" + +"\n\t\t</X>" + +"\n\t</c>" + +"\n\t<d>" + +"\n\t\t<X>" + +"\n\t\t\t<fx>fx1</fx>" + +"\n\t\t</X>" + +"\n\t</d>" + +"\n</object>\n", + "<object>" + +"<a>" + +"<fx>fx1</fx>" + +"</a>" + +"<b _type='X'>" + +"<fx>fx1</fx>" + +"</b>" + +"<c>" + +"<X>" + +"<fx>fx1</fx>" + +"</X>" + +"</c>" + +"<d>" + +"<X>" + +"<fx>fx1</fx>" + +"</X>" + +"</d>" + +"</object>", + }, + { + "BeanWithChildName", + new BeanWithChildName().init(), + "<object><a><X>foo</X><X>bar</X></a><b><Y>123</Y><Y>456</Y></b></object>", + "<object>\n\t<a>\n\t\t<X>foo</X>\n\t\t<X>bar</X>\n\t</a>\n\t<b>\n\t\t<Y>123</Y>\n\t\t<Y>456</Y>\n\t</b>\n</object>\n", + "<object><a><X>foo</X><X>bar</X></a><b><Y>123</Y><Y>456</Y></b></object>", + }, + { + "BeanWithXmlFormatAttrProperty", + new BeanWithXmlFormatAttrProperty().init(), + "<object a='foo' b='123'/>", + "<object a='foo' b='123'/>\n", + "<object a='foo' b='123'/>", + }, + { + "BeanWithXmlFormatAttrs", + new BeanWithXmlFormatAttrs().init(), + "<object a='foo' b='123'/>", + "<object a='foo' b='123'/>\n", + "<object a='foo' b='123'/>", + }, + { + "BeanWithXmlFormatElementProperty", + new BeanWithXmlFormatElementProperty().init(), + "<object a='foo'><b>123</b></object>", + "<object a='foo'>\n\t<b>123</b>\n</object>\n", + "<object a='foo'><b>123</b></object>", + }, + { + "BeanWithXmlFormatAttrsProperty", + new BeanWithXmlFormatAttrsProperty().init(), + "<object k1='foo' k2='123' b='456'/>", + "<object k1='foo' k2='123' b='456'/>\n", + "<object k1='foo' k2='123' b='456'/>", + }, + { + "BeanWithXmlFormatCollapsedProperty", + new BeanWithXmlFormatCollapsedProperty().init(), + "<object><A>foo</A><A>bar</A><B>123</B><B>456</B></object>", + "<object>\n\t<A>foo</A>\n\t<A>bar</A>\n\t<B>123</B>\n\t<B>456</B>\n</object>\n", + "<object><A>foo</A><A>bar</A><B>123</B><B>456</B></object>", + }, + { + "BeanWithXmlFormatTextProperty", + new BeanWithXmlFormatTextProperty().init(), + "<object a='foo'>bar</object>", + "<object a='foo'>bar</object>\n", + "<object a='foo'>bar</object>", + }, + { + "BeanWithXmlFormatXmlTextProperty", + new BeanWithXmlFormatXmlTextProperty().init(), + "<object a='foo'>bar<b>baz</b>qux</object>", + "<object a='foo'>bar<b>baz</b>qux</object>\n", + "<object a='foo'>bar<b>baz</b>qux</object>", + }, + { + "BeanWithXmlFormatElementsPropertyCollection", + new BeanWithXmlFormatElementsPropertyCollection().init(), + "<object a='foo'><string>bar</string><string>baz</string><number>123</number><boolean>true</boolean><null/></object>", + "<object a='foo'>\n\t<string>bar</string>\n\t<string>baz</string>\n\t<number>123</number>\n\t<boolean>true</boolean>\n\t<null/>\n</object>\n", + "<object a='foo'><string>bar</string><string>baz</string><number>123</number><boolean>true</boolean><null/></object>", + }, + { + "BeanWithMixedContent", + new BeanWithMixedContent().init(), + "<object>foo<X fx='fx1'/>bar<Y fy='fy1'/>baz</object>", + "<object>foo<X fx='fx1'/>bar<Y fy='fy1'/>baz</object>\n", // Mixed content doesn't use whitespace! + "<object>foo<X fx='fx1'/>bar<Y fy='fy1'/>baz</object>", + }, + { + "BeanWithSpecialCharacters", + new BeanWithSpecialCharacters().init(), + "<object><a>_x0020_ _x0008__x000C_
	
 _x0020_</a></object>", + "<object>\n\t<a>_x0020_ _x0008__x000C_
	
 _x0020_</a>\n</object>\n", + "<object><a>_x0020_ _x0008__x000C_
	
 _x0020_</a></object>" + }, + { + "BeanWithSpecialCharacters2", + new BeanWithSpecialCharacters2().init(), + "<_x0020__x0020__x0008__x000C__x000A__x0009__x000D__x0020__x0020_><_x0020__x0020__x0008__x000C__x000A__x0009__x000D__x0020__x0020_>_x0020_ _x0008__x000C_
	
 _x0020_</_x0020__x0020__x0008__x000C__x000A__x0009__x000D__x0020__x0020_></_x0020__x0020__x0008__x000C__x000A__x0009__x000D__x0020__x0020_>", + "<_x0020__x0020__x0008__x000C__x000A__x0009__x000D__x0020__x0020_>\n\t<_x0020__x0020__x0008__x000C__x000A__x0009__x000D__x0020__x0020_>_x0020_ _x0008__x000C_
	
 _x0020_</_x0020__x0020__x0008__x000C__x000A__x0009__x000D__x0020__x0020_>\n</_x0020__x0020__x0008__x000C__x000A__x0009__x000D__x0020__x0020_>\n", + "<_x0020__x0020__x0008__x000C__x000A__x0009__x000D__x0020__x0020_><_x0020__x0020__x0008__x000C__x000A__x0009__x000D__x0020__x0020_>_x0020_ _x0008__x000C_
	
 _x0020_</_x0020__x0020__x0008__x000C__x000A__x0009__x000D__x0020__x0020_></_x0020__x0020__x0008__x000C__x000A__x0009__x000D__x0020__x0020_>" + }, + { + "BeanWithNullProperties", + new BeanWithNullProperties(), + "<object/>", + "<object/>\n", + "<object/>" + }, + { + "BeanWithAbstractFields", + new BeanWithAbstractFields().init(), + "<object>" + +"<a>" + +"<a>foo</a>" + +"</a>" + +"<ia _type='A'>" + +"<a>foo</a>" + +"</ia>" + +"<aa _type='A'>" + +"<a>foo</a>" + +"</aa>" + +"<o _type='A'>" + +"<a>foo</a>" + +"</o>" + +"</object>", + "<object>\n" + +"\t<a>\n" + +"\t\t<a>foo</a>\n" + +"\t</a>\n" + +"\t<ia _type='A'>\n" + +"\t\t<a>foo</a>\n" + +"\t</ia>\n" + +"\t<aa _type='A'>\n" + +"\t\t<a>foo</a>\n" + +"\t</aa>\n" + +"\t<o _type='A'>\n" + +"\t\t<a>foo</a>\n" + +"\t</o>\n" + +"</object>\n", + "<object>" + +"<a>" + +"<a>foo</a>" + +"</a>" + +"<ia _type='A'>" + +"<a>foo</a>" + +"</ia>" + +"<aa _type='A'>" + +"<a>foo</a>" + +"</aa>" + +"<o _type='A'>" + +"<a>foo</a>" + +"</o>" + +"</object>", + }, + { + "BeanWithAbstractArrayFields", + new BeanWithAbstractArrayFields().init(), + "<object>" + +"<a>" + +"<A>" + +"<a>foo</a>" + +"</A>" + +"</a>" + +"<ia1>" + +"<A>" + +"<a>foo</a>" + +"</A>" + +"</ia1>" + +"<ia2>" + +"<A>" + +"<a>foo</a>" + +"</A>" + +"</ia2>" + +"<aa1>" + +"<A>" + +"<a>foo</a>" + +"</A>" + +"</aa1>" + +"<aa2>" + +"<A>" + +"<a>foo</a>" + +"</A>" + +"</aa2>" + +"<o1>" + +"<A>" + +"<a>foo</a>" + +"</A>" + +"</o1>" + +"<o2>" + +"<A>" + +"<a>foo</a>" + +"</A>" + +"</o2>" + +"</object>", + "<object>\n" + +"\t<a>\n" + +"\t\t<A>\n" + +"\t\t\t<a>foo</a>\n" + +"\t\t</A>\n" + +"\t</a>\n" + +"\t<ia1>\n" + +"\t\t<A>\n" + +"\t\t\t<a>foo</a>\n" + +"\t\t</A>\n" + +"\t</ia1>\n" + +"\t<ia2>\n" + +"\t\t<A>\n" + +"\t\t\t<a>foo</a>\n" + +"\t\t</A>\n" + +"\t</ia2>\n" + +"\t<aa1>\n" + +"\t\t<A>\n" + +"\t\t\t<a>foo</a>\n" + +"\t\t</A>\n" + +"\t</aa1>\n" + +"\t<aa2>\n" + +"\t\t<A>\n" + +"\t\t\t<a>foo</a>\n" + +"\t\t</A>\n" + +"\t</aa2>\n" + +"\t<o1>\n" + +"\t\t<A>\n" + +"\t\t\t<a>foo</a>\n" + +"\t\t</A>\n" + +"\t</o1>\n" + +"\t<o2>\n" + +"\t\t<A>\n" + +"\t\t\t<a>foo</a>\n" + +"\t\t</A>\n" + +"\t</o2>\n" + +"</object>\n", + "<object>" + +"<a>" + +"<A>" + +"<a>foo</a>" + +"</A>" + +"</a>" + +"<ia1>" + +"<A>" + +"<a>foo</a>" + +"</A>" + +"</ia1>" + +"<ia2>" + +"<A>" + +"<a>foo</a>" + +"</A>" + +"</ia2>" + +"<aa1>" + +"<A>" + +"<a>foo</a>" + +"</A>" + +"</aa1>" + +"<aa2>" + +"<A>" + +"<a>foo</a>" + +"</A>" + +"</aa2>" + +"<o1>" + +"<A>" + +"<a>foo</a>" + +"</A>" + +"</o1>" + +"<o2>" + +"<A>" + +"<a>foo</a>" + +"</A>" + +"</o2>" + +"</object>", + }, + { + "BeanWithAbstractMapFields", + new BeanWithAbstractMapFields().init(), + "<object>" + +"<a>" + +"<k1>" + +"<a>foo</a>" + +"</k1>" + +"</a>" + +"<b>" + +"<k2 _type='A'>" + +"<a>foo</a>" + +"</k2>" + +"</b>" + +"<c>" + +"<k3 _type='A'>" + +"<a>foo</a>" + +"</k3>" + +"</c>" + +"</object>", + "<object>\n" + +"\t<a>\n" + +"\t\t<k1>\n" + +"\t\t\t<a>foo</a>\n" + +"\t\t</k1>\n" + +"\t</a>\n" + +"\t<b>\n" + +"\t\t<k2 _type='A'>\n" + +"\t\t\t<a>foo</a>\n" + +"\t\t</k2>\n" + +"\t</b>\n" + +"\t<c>\n" + +"\t\t<k3 _type='A'>\n" + +"\t\t\t<a>foo</a>\n" + +"\t\t</k3>\n" + +"\t</c>\n" + +"</object>\n", + "<object>" + +"<a>" + +"<k1>" + +"<a>foo</a>" + +"</k1>" + +"</a>" + +"<b>" + +"<k2 _type='A'>" + +"<a>foo</a>" + +"</k2>" + +"</b>" + +"<c>" + +"<k3 _type='A'>" + +"<a>foo</a>" + +"</k3>" + +"</c>" + +"</object>", + }, + { + "BeanWithAbstractMapArrayFields", + new BeanWithAbstractMapArrayFields().init(), + "<object>" + +"<a>" + +"<a1>" + +"<A>" + +"<a>foo</a>" + +"</A>" + +"</a1>" + +"</a>" + +"<ia>" + +"<ia1>" + +"<A>" + +"<a>foo</a>" + +"</A>" + +"</ia1>" + +"<ia2>" + +"<A>" + +"<a>foo</a>" + +"</A>" + +"</ia2>" + +"</ia>" + +"<aa>" + +"<aa1>" + +"<A>" + +"<a>foo</a>" + +"</A>" + +"</aa1>" + +"<aa2>" + +"<A>" + +"<a>foo</a>" + +"</A>" + +"</aa2>" + +"</aa>" + +"<o>" + +"<o1>" + +"<A>" + +"<a>foo</a>" + +"</A>" + +"</o1>" + +"<o2>" + +"<A>" + +"<a>foo</a>" + +"</A>" + +"</o2>" + +"</o>" + +"</object>", + "<object>\n" + +"\t<a>\n" + +"\t\t<a1>\n" + +"\t\t\t<A>\n" + +"\t\t\t\t<a>foo</a>\n" + +"\t\t\t</A>\n" + +"\t\t</a1>\n" + +"\t</a>\n" + +"\t<ia>\n" + +"\t\t<ia1>\n" + +"\t\t\t<A>\n" + +"\t\t\t\t<a>foo</a>\n" + +"\t\t\t</A>\n" + +"\t\t</ia1>\n" + +"\t\t<ia2>\n" + +"\t\t\t<A>\n" + +"\t\t\t\t<a>foo</a>\n" + +"\t\t\t</A>\n" + +"\t\t</ia2>\n" + +"\t</ia>\n" + +"\t<aa>\n" + +"\t\t<aa1>\n" + +"\t\t\t<A>\n" + +"\t\t\t\t<a>foo</a>\n" + +"\t\t\t</A>\n" + +"\t\t</aa1>\n" + +"\t\t<aa2>\n" + +"\t\t\t<A>\n" + +"\t\t\t\t<a>foo</a>\n" + +"\t\t\t</A>\n" + +"\t\t</aa2>\n" + +"\t</aa>\n" + +"\t<o>\n" + +"\t\t<o1>\n" + +"\t\t\t<A>\n" + +"\t\t\t\t<a>foo</a>\n" + +"\t\t\t</A>\n" + +"\t\t</o1>\n" + +"\t\t<o2>\n" + +"\t\t\t<A>\n" + +"\t\t\t\t<a>foo</a>\n" + +"\t\t\t</A>\n" + +"\t\t</o2>\n" + +"\t</o>\n" + +"</object>\n", + "<object>" + +"<a>" + +"<a1>" + +"<A>" + +"<a>foo</a>" + +"</A>" + +"</a1>" + +"</a>" + +"<ia>" + +"<ia1>" + +"<A>" + +"<a>foo</a>" + +"</A>" + +"</ia1>" + +"<ia2>" + +"<A>" + +"<a>foo</a>" + +"</A>" + +"</ia2>" + +"</ia>" + +"<aa>" + +"<aa1>" + +"<A>" + +"<a>foo</a>" + +"</A>" + +"</aa1>" + +"<aa2>" + +"<A>" + +"<a>foo</a>" + +"</A>" + +"</aa2>" + +"</aa>" + +"<o>" + +"<o1>" + +"<A>" + +"<a>foo</a>" + +"</A>" + +"</o1>" + +"<o2>" + +"<A>" + +"<a>foo</a>" + +"</A>" + +"</o2>" + +"</o>" + +"</object>", + }, + { + "BeanWithWhitespaceTextFields-1", + new BeanWithWhitespaceTextFields().init(null), + "<object/>", + "<object/>\n", + "<object/>", + }, + { + "BeanWithWhitespaceTextFields-2", + new BeanWithWhitespaceTextFields().init(""), + "<object>_xE000_</object>", + "<object>_xE000_</object>\n", + "<object>_xE000_</object>", + }, + { + "BeanWithWhitespaceTextFields-3", + new BeanWithWhitespaceTextFields().init(" "), + "<object>_x0020_</object>", + "<object>_x0020_</object>\n", + "<object>_x0020_</object>", + }, + { + "BeanWithWhitespaceTextFields-4", + new BeanWithWhitespaceTextFields().init(" "), + "<object>_x0020__x0020_</object>", + "<object>_x0020__x0020_</object>\n", + "<object>_x0020__x0020_</object>", + }, + { + "BeanWithWhitespaceTextFields-5", + new BeanWithWhitespaceTextFields().init(" foo\n\tbar "), + "<object>_x0020_foo
	bar_x0020_</object>", + "<object>_x0020_foo
	bar_x0020_</object>\n", + "<object>_x0020_foo
	bar_x0020_</object>", + }, + { + "BeanWithWhitespaceTextPwsFields-1", + new BeanWithWhitespaceTextPwsFields().init(null), + "<object/>", + "<object/>\n", + "<object/>", + }, + { + "BeanWithWhitespaceTextPwsFields-2", + new BeanWithWhitespaceTextPwsFields().init(""), + "<object>_xE000_</object>", + "<object>_xE000_</object>\n", + "<object>_xE000_</object>", + }, + { + "BeanWithWhitespaceTextPwsFields-3", + new BeanWithWhitespaceTextPwsFields().init(" "), + "<object> </object>", + "<object> </object>\n", + "<object> </object>", + }, + { + "BeanWithWhitespaceTextPwsFields-4", + new BeanWithWhitespaceTextPwsFields().init(" "), + "<object> </object>", + "<object> </object>\n", + "<object> </object>", + }, + { + "BeanWithWhitespaceTextPwsFields-5", + new BeanWithWhitespaceTextPwsFields().init(" foobar "), + "<object> foobar </object>", + "<object> foobar </object>\n", + "<object> foobar </object>", + }, + { + "BeanWithWhitespaceMixedFields-1", + new BeanWithWhitespaceMixedFields().init(null), + "<object/>", + "<object/>\n", + "<object/>", + }, + { + "BeanWithWhitespaceMixedFields-2", + new BeanWithWhitespaceMixedFields().init(new String[0]), + "<object/>", + "<object/>\n", + "<object/>", + }, + { + "BeanWithWhitespaceMixedFields-3", + new BeanWithWhitespaceMixedFields().init(new String[]{""}), + "<object>_xE000_</object>", + "<object>_xE000_</object>\n", + "<object>_xE000_</object>", + }, + { + "BeanWithWhitespaceMixedFields-4", + new BeanWithWhitespaceMixedFields().init(new String[]{" "}), + "<object>_x0020_</object>", + "<object>_x0020_</object>\n", + "<object>_x0020_</object>", + }, + { + "BeanWithWhitespaceMixedFields-5", + new BeanWithWhitespaceMixedFields().init(new String[]{" "}), + "<object>_x0020__x0020_</object>", + "<object>_x0020__x0020_</object>\n", + "<object>_x0020__x0020_</object>", + }, + { + "BeanWithWhitespaceMixedFields-6", + new BeanWithWhitespaceMixedFields().init(new String[]{" foobar "}), + "<object>_x0020_ foobar _x0020_</object>", + "<object>_x0020_ foobar _x0020_</object>\n", + "<object>_x0020_ foobar _x0020_</object>", + }, + { + "BeanWithWhitespaceMixedPwsFields-1", + new BeanWithWhitespaceMixedPwsFields().init(null), + "<object/>", + "<object/>\n", + "<object/>", + }, + { + "BeanWithWhitespaceMixedPwsFields-2", + new BeanWithWhitespaceMixedPwsFields().init(new String[0]), + "<object/>", + "<object/>\n", + "<object/>", + }, + { + "BeanWithWhitespaceMixedPwsFields-3", + new BeanWithWhitespaceMixedPwsFields().init(new String[]{""}), + "<object>_xE000_</object>", + "<object>_xE000_</object>\n", + "<object>_xE000_</object>", + }, + { + "BeanWithWhitespaceMixedPwsFields-4", + new BeanWithWhitespaceMixedPwsFields().init(new String[]{" "}), + "<object> </object>", + "<object> </object>\n", + "<object> </object>", + }, + { + "BeanWithWhitespaceMixedPwsFields-5", + new BeanWithWhitespaceMixedPwsFields().init(new String[]{" "}), + "<object> </object>", + "<object> </object>\n", + "<object> </object>", + }, + { + "BeanWithWhitespaceMixedPwsFields-6", + new BeanWithWhitespaceMixedPwsFields().init(new String[]{" foobar "}), + "<object> foobar </object>", + "<object> foobar </object>\n", + "<object> foobar </object>", + }, + }); + } + + private String label, e1, e2, e3; + private Object in; + + public BasicXmlTest(String label, Object in, String e1, String e2, String e3) throws Exception { + this.label = label; + this.in = in; + this.e1 = e1; + this.e2 = e2; + this.e3 = e3; + } + + @Test + public void serializeNormal() { + try { + String r = s1.serialize(in); + assertEquals(label + " serialize-normal failed", e1, r); + } catch (AssertionError e) { + throw e; + } catch (Throwable e) { + throw new RuntimeException(label + " test failed", e); + } + } + + @Test + public void parseNormal() { + try { + String r = s1.serialize(in); + Class<?> c = in == null ? Object.class : in.getClass(); + Object o = parser.parse(r, c); + r = s1.serialize(o); + assertEquals(label + " parse-normal failed", e1, r); + } catch (AssertionError e) { + throw e; + } catch (Throwable e) { + throw new RuntimeException(label + " test failed", e); + } + } + + @Test + public void serializeReadable() { + try { + String r = s2.serialize(in); + assertEquals(label + " serialize-readable failed", e2, r); + } catch (AssertionError e) { + throw e; + } catch (Throwable e) { + throw new RuntimeException(label + " test failed", e); + } + } + + @Test + public void parseReadable() { + try { + String r = s2.serialize(in); + Class<?> c = in == null ? Object.class : in.getClass(); + Object o = parser.parse(r, c); + r = s2.serialize(o); + assertEquals(label + " parse-readable failed", e2, r); + } catch (AssertionError e) { + throw e; + } catch (Throwable e) { + throw new RuntimeException(label + " test failed", e); + } + } + + @Test + public void serializeNsEnabled() { + try { + String r = s3.serialize(in); + assertEquals(label + " serialize-ns-enabled failed", e3, r); + } catch (AssertionError e) { + throw e; + } catch (Throwable e) { + throw new RuntimeException(label + " test failed", e); + } + } + + @Test + public void parseNsEnabled() { + try { + String r = s3.serialize(in); + Class<?> c = in == null ? Object.class : in.getClass(); + Object o = parser.parse(r, c); + r = s3.serialize(o); + assertEquals(label + " parse-ns-enabled failed", e3, r); + } catch (AssertionError e) { + throw e; + } catch (Throwable e) { + throw new RuntimeException(label + " test failed", e); + } + } + + + //-------------------------------------------------------------------------------- + // Test beans + //-------------------------------------------------------------------------------- + + public static class MapWithStrings extends LinkedHashMap<String,String> { + public MapWithStrings append(String key, String value) { + put(key, value); + return this; + } + } + + public static class MapWithNumbers extends LinkedHashMap<String,Number> { + public MapWithNumbers append(String key, Number value) { + put(key, value); + return this; + } + } + + public static class MapWithObjects extends LinkedHashMap<String,Object> { + public MapWithObjects append(String key, Object value) { + put(key, value); + return this; + } + } + + public static class ListWithStrings extends ArrayList<String> { + public ListWithStrings append(String value) { + this.add(value); + return this; + } + } + + public static class ListWithNumbers extends ArrayList<Number> { + public ListWithNumbers append(Number value) { + this.add(value); + return this; + } + } + + public static class ListWithObjects extends ArrayList<Object> { + public ListWithObjects append(Object value) { + this.add(value); + return this; + } + } + + public static class BeanWithNormalProperties { + public String a; + public int b; + public Object c; + public Object d; + public Bean1a e; + public String[] f; + public int[] g; + + BeanWithNormalProperties init() { + a = "foo"; + b = 123; + c = "bar"; + d = 456; + e = new Bean1a().init(); + f = new String[]{ "baz" }; + g = new int[]{ 789 }; + return this; + } + } + + public static class Bean1a { + public String h; + + Bean1a init() { + h = "qux"; + return this; + } + } + + public static class BeanWithMapProperties { + @BeanProperty(type=MapWithStrings.class) + public Map<String,String> a; + @BeanProperty(type=MapWithNumbers.class) + public Map<String,Number> b; + @BeanProperty(type=MapWithObjects.class) + public Map<String,Object> c; + + BeanWithMapProperties init() { + a = new MapWithStrings().append("k1","foo"); + b = new MapWithNumbers().append("k2",123); + c = new MapWithObjects().append("k3","bar").append("k4",456).append("k5",true).append("k6",null); + return this; + } + } + + @Bean(typeName="X") + public static class BeanWithTypeName { + public int a; + public String b; + + BeanWithTypeName init() { + a = 123; + b = "foo"; + return this; + } + } + + @Bean(beanDictionary={B.class}) + public static class BeanWithPropertiesWithTypeNames { + public B b1; + public Object b2; + + BeanWithPropertiesWithTypeNames init() { + b1 = new B().init(); + b2 = new B().init(); + return this; + } + } + + @Bean(beanDictionary={B.class}) + public static class BeanWithPropertiesWithArrayTypeNames { + public B[] b1; + public Object[] b2; + public Object[] b3; + + BeanWithPropertiesWithArrayTypeNames init() { + b1 = new B[]{new B().init()}; + b2 = new B[]{new B().init()}; + b3 = new Object[]{new B().init()}; + return this; + } + } + + @Bean(beanDictionary={B.class}) + public static class BeanWithPropertiesWith2dArrayTypeNames { + public B[][] b1; + public Object[][] b2; + public Object[][] b3; + + BeanWithPropertiesWith2dArrayTypeNames init() { + b1 = new B[][]{{new B().init()}}; + b2 = new B[][]{{new B().init()}}; + b3 = new Object[][]{{new B().init()}}; + return this; + } + } + + @Bean(beanDictionary={B.class}) + public static class BeanWithPropertiesWithMapTypeNames { + public Map<String,B> b1; + public Map<String,Object> b2; + + BeanWithPropertiesWithMapTypeNames init() { + b1 = new HashMap<String,B>(); + b1.put("k1", new B().init()); + b2 = new HashMap<String,Object>(); + b2.put("k2", new B().init()); + return this; + } + } + + @Bean(typeName="B") + public static class B { + public String b; + + B init() { + b = "foo"; + return this; + } + } + + public static class BeanWithChildTypeNames { + public BeanX a; + @BeanProperty(beanDictionary=BeanX.class) + public Object b; + public BeanX[] c; + @BeanProperty(beanDictionary=BeanX.class) + public Object[] d; + BeanWithChildTypeNames init() { + a = new BeanX().init(); + b = new BeanX().init(); + c = new BeanX[]{new BeanX().init()}; + d = new Object[]{new BeanX().init()}; + return this; + } + } + + public static class BeanWithChildName { + @Xml(childName = "X") + public String[] a; + @Xml(childName = "Y") + public int[] b; + BeanWithChildName init() { + a = new String[] { "foo", "bar" }; + b = new int[] { 123, 456 }; + return this; + } + } + + public static class BeanWithXmlFormatAttrProperty { + @Xml(format=XmlFormat.ATTR) + public String a; + @Xml(format=XmlFormat.ATTR) + public int b; + BeanWithXmlFormatAttrProperty init() { + a = "foo"; + b = 123; + return this; + } + } + + @Xml(format=XmlFormat.ATTRS) + public static class BeanWithXmlFormatAttrs { + public String a; + public int b; + BeanWithXmlFormatAttrs init() { + a = "foo"; + b = 123; + return this; + } + } + + @Xml(format=XmlFormat.ATTRS) + public static class BeanWithXmlFormatElementProperty { + public String a; + @Xml(format=XmlFormat.ELEMENT) + public int b; + BeanWithXmlFormatElementProperty init() { + a = "foo"; + b = 123; + return this; + } + } + + public static class BeanWithXmlFormatAttrsProperty { + @Xml(format=XmlFormat.ATTRS) + public Map<String,Object> a; + @Xml(format=XmlFormat.ATTR) + public int b; + BeanWithXmlFormatAttrsProperty init() { + a = new ObjectMap().append("k1", "foo").append("k2", 123); + b = 456; + return this; + } + } + + public static class BeanWithXmlFormatCollapsedProperty { + @Xml(childName="A",format=XmlFormat.COLLAPSED) + public String[] a; + @Xml(childName="B",format=XmlFormat.COLLAPSED) + public int[] b; + BeanWithXmlFormatCollapsedProperty init() { + a = new String[]{"foo","bar"}; + b = new int[]{123,456}; + return this; + } + } + + public static class BeanWithXmlFormatTextProperty { + @Xml(format=XmlFormat.ATTR) + public String a; + @Xml(format=XmlFormat.TEXT) + public String b; + BeanWithXmlFormatTextProperty init() { + a = "foo"; + b = "bar"; + return this; + } + } + + public static class BeanWithXmlFormatXmlTextProperty { + @Xml(format=XmlFormat.ATTR) + public String a; + @Xml(format=XmlFormat.XMLTEXT) + public String b; + BeanWithXmlFormatXmlTextProperty init() { + a = "foo"; + b = "bar<b>baz</b>qux"; + return this; + } + } + + public static class BeanWithXmlFormatElementsPropertyCollection { + @Xml(format=XmlFormat.ATTR) + public String a; + @Xml(format=XmlFormat.ELEMENTS) + public Object[] b; + BeanWithXmlFormatElementsPropertyCollection init() { + a = "foo"; + b = new Object[]{"bar","baz",123,true,null}; + return this; + } + } + + public static class BeanWithMixedContent { + @Xml(format=XmlFormat.MIXED) + @BeanProperty(beanDictionary={BeanXSimple.class, BeanYSimple.class}) + public Object[] a; + BeanWithMixedContent init() { + a = new Object[]{ + "foo", + new BeanXSimple().init(), + "bar", + new BeanYSimple().init(), + "baz" + }; + return this; + } + } + + @Bean(typeName="X") + public static class BeanX { + public String fx; + BeanX init() { + fx = "fx1"; + return this; + } + } + + @Bean(typeName="X") + public static class BeanXSimple { + @Xml(format=XmlFormat.ATTR) + public String fx; + BeanXSimple init() { + fx = "fx1"; + return this; + } + } + + @Bean(typeName="Y") + public static class BeanY { + public String fy; + BeanY init() { + fy = "fy1"; + return this; + } + } + + @Bean(typeName="Y") + public static class BeanYSimple { + @Xml(format=XmlFormat.ATTR) + public String fy; + BeanYSimple init() { + fy = "fy1"; + return this; + } + } + + public static class BeanWithSpecialCharacters { + public String a; + + BeanWithSpecialCharacters init() { + a = " \b\f\n\t\r "; + return this; + } + } + + @Bean(typeName=" \b\f\n\t\r ") + public static class BeanWithSpecialCharacters2 { + + @BeanProperty(name=" \b\f\n\t\r ") + public String a; + + BeanWithSpecialCharacters2 init() { + a = " \b\f\n\t\r "; + return this; + } + } + + public static class BeanWithNullProperties { + public String a; + public String[] b; + } + + @Bean(beanDictionary={A.class}) + public static class BeanWithAbstractFields { + public A a; + public IA ia; + public AA aa; + public Object o; + + BeanWithAbstractFields init() { + ia = new A().init(); + aa = new A().init(); + a = new A().init(); + o = new A().init(); + return this; + } + } + + @Bean(beanDictionary={A.class}) + public static class BeanWithAbstractArrayFields { + public A[] a; + public IA[] ia1, ia2; + public AA[] aa1, aa2; + public Object[] o1, o2; + + BeanWithAbstractArrayFields init() { + a = new A[]{new A().init()}; + ia1 = new A[]{new A().init()}; + aa1 = new A[]{new A().init()}; + o1 = new A[]{new A().init()}; + ia2 = new IA[]{new A().init()}; + aa2 = new AA[]{new A().init()}; + o2 = new Object[]{new A().init()}; + return this; + } + } + + @Bean(beanDictionary={A.class}) + public static class BeanWithAbstractMapFields { + public Map<String,A> a; + public Map<String,AA> b; + public Map<String,Object> c; + + BeanWithAbstractMapFields init() { + a = new HashMap<String,A>(); + b = new HashMap<String,AA>(); + c = new HashMap<String,Object>(); + a.put("k1", new A().init()); + b.put("k2", new A().init()); + c.put("k3", new A().init()); + return this; + } + } + + @Bean(beanDictionary={A.class}) + public static class BeanWithAbstractMapArrayFields { + public Map<String,A[]> a; + public Map<String,IA[]> ia; + public Map<String,AA[]> aa; + public Map<String,Object[]> o; + + BeanWithAbstractMapArrayFields init() { + a = new LinkedHashMap<String,A[]>(); + ia = new LinkedHashMap<String,IA[]>(); + aa = new LinkedHashMap<String,AA[]>(); + o = new LinkedHashMap<String,Object[]>(); + a.put("a1", new A[]{new A().init()}); + ia.put("ia1", new A[]{new A().init()}); + ia.put("ia2", new IA[]{new A().init()}); + aa.put("aa1", new A[]{new A().init()}); + aa.put("aa2", new AA[]{new A().init()}); + o.put("o1", new A[]{new A().init()}); + o.put("o2", new Object[]{new A().init()}); + return this; + } + } + + public static interface IA { + public String getA(); + public void setA(String a); + } + + public static abstract class AA implements IA {} + + @Bean(typeName="A") + public static class A extends AA { + private String a; + + @Override + public String getA() { + return a; + } + + @Override + public void setA(String a) { + this.a = a; + } + + A init() { + this.a = "foo"; + return this; + } + } + + public static class BeanWithWhitespaceTextFields { + @Xml(format=XmlFormat.TEXT) + public String a; + + public BeanWithWhitespaceTextFields init(String s) { + a = s; + return this; + } + } + + public static class BeanWithWhitespaceTextPwsFields { + @Xml(format=XmlFormat.TEXT_PWS) + public String a; + + public BeanWithWhitespaceTextPwsFields init(String s) { + a = s; + return this; + } + } + + public static class BeanWithWhitespaceMixedFields { + @Xml(format=XmlFormat.MIXED) + public String[] a; + + public BeanWithWhitespaceMixedFields init(String[] s) { + a = s; + return this; + } + } + + public static class BeanWithWhitespaceMixedPwsFields { + @Xml(format=XmlFormat.MIXED_PWS) + public String[] a; + + public BeanWithWhitespaceMixedPwsFields init(String[] s) { + a = s; + return this; + } + } +}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/75b0d8ee/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonParserTest.java ---------------------------------------------------------------------- diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonParserTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonParserTest.java new file mode 100755 index 0000000..5fba9a1 --- /dev/null +++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonParserTest.java @@ -0,0 +1,178 @@ +// *************************************************************************************************************************** +// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * +// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * +// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * +// * with the License. You may obtain a copy of the License at * +// * * +// * http://www.apache.org/licenses/LICENSE-2.0 * +// * * +// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * +// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * +// * specific language governing permissions and limitations under the License. * +// *************************************************************************************************************************** +package org.apache.juneau.xml; + +import static org.junit.Assert.*; + +import java.util.*; + +import org.apache.juneau.*; +import org.apache.juneau.parser.*; +import org.junit.*; + +@SuppressWarnings({"rawtypes","serial","javadoc"}) +public class CommonParserTest { + + //==================================================================================================== + // testFromSerializer + //==================================================================================================== + @Test + public void testFromSerializer() throws Exception { + ReaderParser p = XmlParser.DEFAULT; + + Map m = null; + m = (Map)p.parse("<object><a _type='number'>1</a></object>", Object.class); + assertEquals(1, m.get("a")); + m = (Map)p.parse("<object><a _type='number'>1</a><b _type='string'>foo bar</b></object>", Object.class); + assertEquals(1, m.get("a")); + assertEquals("foo bar", m.get("b")); + m = (Map)p.parse("<object><a _type='number'>1</a><b _type='string'>foo bar</b><c _type='boolean'>false</c></object>", Object.class); + assertEquals(1, m.get("a")); + assertEquals(false, m.get("c")); + m = (Map)p.parse(" <object> <a _type='number'> 1 </a> <b _type='string'> foo </b> <c _type='boolean'> false </c> </object> ", Object.class); + assertEquals(1, m.get("a")); + assertEquals("foo", m.get("b")); + assertEquals(false, m.get("c")); + + m = (Map)p.parse("<object><x _type='string'>org.apache.juneau.test.Person</x><addresses _type='array'><object><x _type='string'>org.apache.juneau.test.Address</x><city _type='string'>city A</city><state _type='string'>state A</state><street _type='string'>street A</street><zip _type='number'>12345</zip></object></addresses></object>", Object.class); + assertEquals("org.apache.juneau.test.Person", m.get("x")); + List l = (List)m.get("addresses"); + assertNotNull(l); + m = (Map)l.get(0); + assertNotNull(m); + assertEquals("org.apache.juneau.test.Address", m.get("x")); + assertEquals("city A", m.get("city")); + assertEquals("state A", m.get("state")); + assertEquals("street A", m.get("street")); + assertEquals(12345, m.get("zip")); + + ObjectList jl = (ObjectList)p.parse("<array><object><attribute _type='string'>value</attribute></object><object><attribute _type='string'>value</attribute></object></array>", Object.class); + assertEquals("value", jl.getObjectMap(0).getString("attribute")); + assertEquals("value", jl.getObjectMap(1).getString("attribute")); + + try { + jl = (ObjectList)p.parse("<array><object><attribute _type='string'>value</attribute></object><object><attribute _type='string'>value</attribute></object></array>", Object.class); + assertEquals("value", jl.getObjectMap(0).getString("attribute")); + assertEquals("value", jl.getObjectMap(1).getString("attribute")); + } catch (Exception e) { + fail(e.getLocalizedMessage()); + } + + A1 t1 = new A1(); + A2 t2 = new A2(); + t2.add(new A3("name0","value0")); + t2.add(new A3("name1","value1")); + t1.list = t2; + String r = XmlSerializer.DEFAULT_NS.serialize(t1); + t1 = p.parse(r, A1.class); + assertEquals("value1", t1.list.get(1).value); + + r = XmlSerializer.DEFAULT_NS.serialize(t1); + t1 = p.parse(r, A1.class); + assertEquals("value1", t1.list.get(1).value); + } + + public static class A1 { + public A2 list; + } + + public static class A2 extends LinkedList<A3> { + } + + public static class A3 { + public String name, value; + public A3(){} + public A3(String name, String value) { + this.name = name; + this.value = value; + } + } + + //==================================================================================================== + // Correct handling of unknown properties. + //==================================================================================================== + @Test + public void testCorrectHandlingOfUnknownProperties() throws Exception { + ReaderParser p = new XmlParserBuilder().ignoreUnknownBeanProperties(true).build(); + B t; + + String in = "<object><a>1</a><unknown>foo</unknown><b>2</b></object>"; + t = p.parse(in, B.class); + assertEquals(t.a, 1); + assertEquals(t.b, 2); + + in = "<object><a>1</a><unknown><object><a _type='string'>foo</a></object></unknown><b>2</b></object>"; + t = p.parse(in, B.class); + assertEquals(t.a, 1); + assertEquals(t.b, 2); + + + try { + p = XmlParser.DEFAULT; + p.parse(in, B.class); + fail("Exception expected"); + } catch (ParseException e) {} + } + + public static class B { + public int a, b; + } + + //==================================================================================================== + // Writing to Collection properties with no setters. + //==================================================================================================== + @Test + public void testCollectionPropertiesWithNoSetters() throws Exception { + + ReaderParser p = XmlParser.DEFAULT; + + String in = "<object><ints _type='array'><number>1</number><number>2</number><number>3</number></ints><beans _type='array'><object><a _type='number'>1</a><b _type='number'>2</b></object></beans></object>"; + C t = p.parse(in, C.class); + assertEquals(t.getInts().size(), 3); + assertEquals(t.getBeans().get(0).b, 2); + } + + public static class C { + private Collection<Integer> ints = new LinkedList<Integer>(); + private List<B> beans = new LinkedList<B>(); + public Collection<Integer> getInts() { + return ints; + } + public List<B> getBeans() { + return beans; + } + } + + //==================================================================================================== + // Parser listeners. + //==================================================================================================== + @Test + public void testParserListeners() throws Exception { + XmlParser p = new XmlParserBuilder().ignoreUnknownBeanProperties(true).listener(MyParserListener.class).build(); + + String in = "<object><a _type='number'>1</a><unknownProperty _type='string'>foo</unknownProperty><b _type='number'>2</b></object>"; + p.parse(in, B.class); + assertEquals(1, MyParserListener.events.size()); + // XML parser may or may not support line numbers. + assertTrue(MyParserListener.events.get(0).startsWith("unknownProperty,")); + } + + public static class MyParserListener extends ParserListener { + final static List<String> events = new LinkedList<String>(); + + @Override /* ParserListener */ + public <T> void onUnknownBeanProperty(ParserSession session, ParserPipe pipe, String propertyName, Class<T> beanClass, T bean, int line, int col) { + events.add(propertyName + "," + line + "," + col); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/75b0d8ee/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonTest.java ---------------------------------------------------------------------- diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonTest.java new file mode 100755 index 0000000..3e8563f --- /dev/null +++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonTest.java @@ -0,0 +1,304 @@ +// *************************************************************************************************************************** +// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * +// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * +// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * +// * with the License. You may obtain a copy of the License at * +// * * +// * http://www.apache.org/licenses/LICENSE-2.0 * +// * * +// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * +// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * +// * specific language governing permissions and limitations under the License. * +// *************************************************************************************************************************** +package org.apache.juneau.xml; + +import static org.apache.juneau.TestUtils.*; +import static org.apache.juneau.xml.annotation.XmlFormat.*; +import static org.junit.Assert.*; + +import java.net.*; +import java.net.URI; +import java.util.*; + +import org.apache.juneau.*; +import org.apache.juneau.annotation.*; +import org.apache.juneau.jena.annotation.*; +import org.apache.juneau.utils.*; +import org.apache.juneau.xml.annotation.*; +import org.junit.*; + +@SuppressWarnings({"serial","javadoc"}) +public class CommonTest { + + //==================================================================================================== + // Trim nulls from beans + //==================================================================================================== + @Test + public void testTrimNullsFromBeans() throws Exception { + XmlSerializerBuilder s = new XmlSerializerBuilder().sq(); + XmlParser p = XmlParser.DEFAULT; + A t1 = A.create(), t2; + + s.trimNullProperties(false); + String r = s.build().serialize(t1); + assertEquals("<object><s1 _type='null'/><s2>s2</s2></object>", r); + t2 = p.parse(r, A.class); + assertEqualObjects(t1, t2); + + s.trimNullProperties(true); + r = s.build().serialize(t1); + assertEquals("<object><s2>s2</s2></object>", r); + t2 = p.parse(r, A.class); + assertEqualObjects(t1, t2); + } + + public static class A { + public String s1, s2; + + public static A create() { + A t = new A(); + t.s2 = "s2"; + return t; + } + } + + //==================================================================================================== + // Trim empty maps + //==================================================================================================== + @Test + public void testTrimEmptyMaps() throws Exception { + XmlSerializerBuilder s = new XmlSerializerBuilder().sq(); + XmlParser p = XmlParser.DEFAULT; + B t1 = B.create(), t2; + String r; + + s.trimEmptyMaps(false); + r = s.build().serialize(t1); + assertEquals("<object><f1/><f2><f2a _type='null'/><f2b><s2>s2</s2></f2b></f2></object>", r); + t2 = p.parse(r, B.class); + assertEqualObjects(t1, t2); + + s.trimEmptyMaps(true); + r = s.build().serialize(t1); + assertEquals("<object><f2><f2a _type='null'/><f2b><s2>s2</s2></f2b></f2></object>", r); + t2 = p.parse(r, B.class); + assertNull(t2.f1); + } + + public static class B { + public TreeMap<String,A> f1, f2; + + public static B create() { + B t = new B(); + t.f1 = new TreeMap<String,A>(); + t.f2 = new TreeMap<String,A>(){{put("f2a",null);put("f2b",A.create());}}; + return t; + } + } + + //==================================================================================================== + // Trim empty lists + //==================================================================================================== + @Test + public void testTrimEmptyLists() throws Exception { + XmlSerializerBuilder s = new XmlSerializerBuilder().sq(); + XmlParser p = XmlParser.DEFAULT; + C t1 = C.create(), t2; + String r; + + s.trimEmptyCollections(false); + r = s.build().serialize(t1); + assertEquals("<object><f1></f1><f2><null/><object><s2>s2</s2></object></f2></object>", r); + t2 = p.parse(r, C.class); + assertEqualObjects(t1, t2); + + s.trimEmptyCollections(true); + r = s.build().serialize(t1); + assertEquals("<object><f2><null/><object><s2>s2</s2></object></f2></object>", r); + t2 = p.parse(r, C.class); + assertNull(t2.f1); + } + + public static class C { + public List<A> f1, f2; + + public static C create() { + C t = new C(); + t.f1 = new AList<A>(); + t.f2 = new AList<A>().append(null).append(A.create()); + return t; + } + } + + //==================================================================================================== + // Trim empty arrays + //==================================================================================================== + @Test + public void testTrimEmptyArrays() throws Exception { + XmlSerializerBuilder s = new XmlSerializerBuilder().sq(); + XmlParser p = XmlParser.DEFAULT; + D t1 = D.create(), t2; + String r; + + s.trimEmptyCollections(false); + r = s.build().serialize(t1); + assertEquals("<object><f1></f1><f2><null/><object><s2>s2</s2></object></f2></object>", r); + t2 = p.parse(r, D.class); + assertEqualObjects(t1, t2); + + s.trimEmptyCollections(true); + r = s.build().serialize(t1); + assertEquals("<object><f2><null/><object><s2>s2</s2></object></f2></object>", r); + t2 = p.parse(r, D.class); + assertNull(t2.f1); + } + + public static class D { + public A[] f1, f2; + + public static D create() { + D t = new D(); + t.f1 = new A[]{}; + t.f2 = new A[]{null, A.create()}; + return t; + } + } + + //==================================================================================================== + // @BeanProperty.properties annotation. + //==================================================================================================== + @Test + public void testBeanPropertyProperties() throws Exception { + XmlSerializer s = XmlSerializer.DEFAULT_SQ; + E1 t = new E1(); + String r = s.serialize(t); + assertEquals( + "<object>" + +"<x1 f2='2'><f1>1</f1></x1>" + +"<x2><f1>1</f1></x2>" + +"<x3><object f2='2'><f1>1</f1></object></x3>" + +"<x4><object f2='2'><f1>1</f1></object></x4>" + +"<x5><object><f1 _type='number'>1</f1></object></x5>" + +"<x6><object><f1 _type='number'>1</f1></object></x6>" + +"</object>", + r); + TestUtils.validateXml(t); + } + + public static class E1 { + @BeanProperty(properties="f1,f2") public E2 x1 = new E2(); + @BeanProperty(properties="f1,f2") public Map<String,Integer> x2 = new AMap<String,Integer>().append("f1",1).append("f3",3); + @BeanProperty(properties="f1,f2") public E2[] x3 = {new E2()}; + @BeanProperty(properties="f1,f2") public List<E2> x4 = new AList<E2>().append(new E2()); + @BeanProperty(properties="f1") public ObjectMap[] x5 = {new ObjectMap().append("f1",1).append("f3",3)}; + @BeanProperty(properties="f1") public List<ObjectMap> x6 = new AList<ObjectMap>().append(new ObjectMap().append("f1",1).append("f3",3)); + } + + public static class E2 { + public int f1 = 1; + @Xml(format=ATTR) public int f2 = 2; + public int f3 = 3; + @Xml(format=ATTR) public int f4 = 4; + } + + //==================================================================================================== + // @BeanProperty.properties annotation on list of beans. + //==================================================================================================== + @Test + public void testBeanPropertyPropertiesOnListOfBeans() throws Exception { + XmlSerializer s = XmlSerializer.DEFAULT_SQ; + List<Test7b> l = new LinkedList<Test7b>(); + Test7b t = new Test7b(); + t.x1.add(new Test7b()); + l.add(t); + String xml = s.serialize(l); + assertEquals("<array><object><x1><object><x2>2</x2></object></x1><x2>2</x2></object></array>", xml); + } + + public static class Test7b { + @BeanProperty(properties="x2") public List<Test7b> x1 = new LinkedList<Test7b>(); + public int x2 = 2; + } + + //==================================================================================================== + // Test that URLs and URIs are serialized and parsed correctly. + //==================================================================================================== + @Test + public void testURIAttr() throws Exception { + XmlSerializer s = XmlSerializer.DEFAULT_SQ; + XmlParser p = XmlParser.DEFAULT; + + G t = new G(); + t.uri = new URI("http://uri"); + t.f1 = new URI("http://f1"); + t.f2 = new URL("http://f2"); + + String xml = s.serialize(t); + t = p.parse(xml, G.class); + assertEquals("http://uri", t.uri.toString()); + assertEquals("http://f1", t.f1.toString()); + assertEquals("http://f2", t.f2.toString()); + } + + public static class G { + @Rdf(beanUri=true) public URI uri; + public URI f1; + public URL f2; + } + + //==================================================================================================== + // Recursion + //==================================================================================================== + @Test + public void testRecursion() throws Exception { + XmlSerializerBuilder s = new XmlSerializerBuilder().enableNamespaces(false); + + R1 r1 = new R1(); + R2 r2 = new R2(); + R3 r3 = new R3(); + r1.r2 = r2; + r2.r3 = r3; + r3.r1 = r1; + + // No recursion detection + try { + s.build().serialize(r1); + fail("Exception expected!"); + } catch (Exception e) { + String msg = e.getLocalizedMessage(); + assertTrue(msg.contains("It's recommended you use the SerializerContext.SERIALIZER_detectRecursions setting to help locate the loop.")); + } + + // Recursion detection, no ignore + s.detectRecursions(true); + try { + s.build().serialize(r1); + fail("Exception expected!"); + } catch (Exception e) { + String msg = e.getLocalizedMessage(); + assertTrue(msg.contains("[0]<noname>:org.apache.juneau.xml.CommonTest$R1")); + assertTrue(msg.contains("->[1]r2:org.apache.juneau.xml.CommonTest$R2")); + assertTrue(msg.contains("->[2]r3:org.apache.juneau.xml.CommonTest$R3")); + assertTrue(msg.contains("->[3]r1:org.apache.juneau.xml.CommonTest$R1")); + } + + s.ignoreRecursions(true); + assertEquals("<object><name>foo</name><r2><name>bar</name><r3><name>baz</name></r3></r2></object>", s.build().serialize(r1)); + + // Make sure this doesn't blow up. + s.build().getSchemaSerializer().serialize(r1); + } + + public static class R1 { + public String name = "foo"; + public R2 r2; + } + public static class R2 { + public String name = "bar"; + public R3 r3; + } + public static class R3 { + public String name = "baz"; + public R1 r1; + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/75b0d8ee/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonXmlTest.java ---------------------------------------------------------------------- diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonXmlTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonXmlTest.java new file mode 100755 index 0000000..031a879 --- /dev/null +++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonXmlTest.java @@ -0,0 +1,80 @@ +// *************************************************************************************************************************** +// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * +// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * +// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * +// * with the License. You may obtain a copy of the License at * +// * * +// * http://www.apache.org/licenses/LICENSE-2.0 * +// * * +// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * +// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * +// * specific language governing permissions and limitations under the License. * +// *************************************************************************************************************************** +package org.apache.juneau.xml; + +import static org.apache.juneau.TestUtils.*; +import static org.apache.juneau.xml.annotation.XmlFormat.*; +import static org.junit.Assert.*; + +import java.net.*; + +import org.apache.juneau.xml.annotation.*; +import org.junit.*; + +@SuppressWarnings("javadoc") +public class CommonXmlTest { + + //==================================================================================================== + // Test 18a - @Bean.uri annotation + //==================================================================================================== + @Test + public void testBeanUriAnnotation() throws Exception { + XmlParser p = XmlParser.DEFAULT; + XmlSerializer s = XmlSerializer.DEFAULT_SQ; + + A t = new A("http://foo", 123, "bar"); + String xml = s.serialize(t); + assertEquals("<object url='http://foo' id='123'><name>bar</name></object>", xml); + + t = p.parse(xml, A.class); + assertEquals("http://foo", t.url.toString()); + assertEquals(123, t.id); + assertEquals("bar", t.name); + + validateXml(t, s); + } + + public static class A { + @Xml(format=XmlFormat.ATTR) public URL url; + @Xml(format=ATTR) public int id; + public String name; + public A() {} + public A(String url, int id, String name) throws Exception { + this.url = new URL(url); + this.id = id; + this.name = name; + } + } + + //==================================================================================================== + // Bean.uri annotation, only uri property + //==================================================================================================== + @Test + public void testBeanUriAnnotationOnlyUriProperty() throws Exception { + XmlSerializer s = new XmlSerializerBuilder().sq().addNamespaceUrisToRoot(false).build(); + + B t = new B("http://foo"); + String xml = s.serialize(t); + assertEquals("<object url='http://foo'><url2>http://foo/2</url2></object>", xml); + } + + public static class B { + @Xml(format=XmlFormat.ATTR) public URL url; + public URL url2; + public B() {} + public B(String url) throws Exception { + this.url = new URL(url); + this.url2 = new URL(url+"/2"); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/75b0d8ee/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/InvalidXmlBeansTest.java ---------------------------------------------------------------------- diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/InvalidXmlBeansTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/InvalidXmlBeansTest.java new file mode 100644 index 0000000..8d115a8 --- /dev/null +++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/xml/InvalidXmlBeansTest.java @@ -0,0 +1,230 @@ +// *************************************************************************************************************************** +// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * +// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * +// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * +// * with the License. You may obtain a copy of the License at * +// * * +// * http://www.apache.org/licenses/LICENSE-2.0 * +// * * +// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * +// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * +// * specific language governing permissions and limitations under the License. * +// *************************************************************************************************************************** +package org.apache.juneau.xml; + +import static org.junit.Assert.*; + +import java.util.*; + +import org.apache.juneau.*; +import org.apache.juneau.xml.annotation.*; +import org.junit.*; +import org.junit.runner.*; +import org.junit.runners.*; + +/** + * Verifies that the correct error messages are displayed when you do something wrong with the @Xml annotation. + */ +@RunWith(Parameterized.class) +@SuppressWarnings({"javadoc"}) +public class InvalidXmlBeansTest { + + private static final XmlSerializer + s1 = XmlSerializer.DEFAULT_SQ; + + @Parameterized.Parameters + public static Collection<Object[]> getParameters() { + return Arrays.asList(new Object[][] { + + { + "BeanWithAttrFormat", + new BeanWithAttrFormat(), + "org.apache.juneau.xml.InvalidXmlBeansTest$BeanWithAttrFormat: Invalid format specified in @Xml annotation on bean: ATTR. Must be one of the following: DEFAULT,ATTRS,ELEMENTS,VOID", + }, + { + "BeanWithElementFormat", + new BeanWithElementFormat(), + "org.apache.juneau.xml.InvalidXmlBeansTest$BeanWithElementFormat: Invalid format specified in @Xml annotation on bean: ELEMENT. Must be one of the following: DEFAULT,ATTRS,ELEMENTS,VOID", + }, + { + "BeanWithCollapsedFormat", + new BeanWithCollapsedFormat(), + "org.apache.juneau.xml.InvalidXmlBeansTest$BeanWithCollapsedFormat: Invalid format specified in @Xml annotation on bean: COLLAPSED. Must be one of the following: DEFAULT,ATTRS,ELEMENTS,VOID", + }, + { + "BeanWithMixedFormat", + new BeanWithMixedFormat(), + "org.apache.juneau.xml.InvalidXmlBeansTest$BeanWithMixedFormat: Invalid format specified in @Xml annotation on bean: MIXED. Must be one of the following: DEFAULT,ATTRS,ELEMENTS,VOID", + }, + { + "BeanWithMultipleAttrs", + new BeanWithMultipleAttrs(), + "org.apache.juneau.xml.InvalidXmlBeansTest$BeanWithMultipleAttrs: Multiple instances of ATTRS properties defined on class. Only one property can be designated as such.", + }, + { + "BeanWithWrongAttrsType", + new BeanWithWrongAttrsType(), + "org.apache.juneau.xml.InvalidXmlBeansTest$BeanWithWrongAttrsType: Invalid type for ATTRS property. Only properties of type Map and bean can be used.", + }, + { + "BeanWithMulipleElements", + new BeanWithMulipleElements(), + "org.apache.juneau.xml.InvalidXmlBeansTest$BeanWithMulipleElements: Multiple instances of ELEMENTS properties defined on class. Only one property can be designated as such.", + }, + { + "BeanWithWrongElementsType", + new BeanWithWrongElementsType(), + "org.apache.juneau.xml.InvalidXmlBeansTest$BeanWithWrongElementsType: Invalid type for ELEMENTS property. Only properties of type Collection and array can be used.", + }, + { + "BeanWithMulipleMixed", + new BeanWithMulipleMixed(), + "org.apache.juneau.xml.InvalidXmlBeansTest$BeanWithMulipleMixed: Multiple instances of MIXED properties defined on class. Only one property can be designated as such.", + }, + { + "BeanWithConflictingChildNames", + new BeanWithConflictingChildNames(), + "org.apache.juneau.xml.InvalidXmlBeansTest$BeanWithConflictingChildNames: Multiple properties found with the child name 'X'.", + }, + { + "BeanWithElementsAndMixed", + new BeanWithElementsAndMixed(), + "org.apache.juneau.xml.InvalidXmlBeansTest$BeanWithElementsAndMixed: ELEMENTS and MIXED properties found on the same bean. Only one property can be designated as such.", + }, + { + "BeanWithElementsAndElement", + new BeanWithElementsAndElement(), + "org.apache.juneau.xml.InvalidXmlBeansTest$BeanWithElementsAndElement: ELEMENTS and ELEMENT properties found on the same bean. These cannot be mixed.", + }, + { + "BeanWithElementsAndDefault", + new BeanWithElementsAndDefault(), + "org.apache.juneau.xml.InvalidXmlBeansTest$BeanWithElementsAndDefault: ELEMENTS and ELEMENT properties found on the same bean. These cannot be mixed.", + }, + { + "BeanWithElementsAndCollapsed", + new BeanWithElementsAndCollapsed(), + "org.apache.juneau.xml.InvalidXmlBeansTest$BeanWithElementsAndCollapsed: ELEMENTS and COLLAPSED properties found on the same bean. These cannot be mixed.", + }, + { + "BeanWithChildAndPropNameConflict", + new BeanWithChildAndPropNameConflict(), + "org.apache.juneau.xml.InvalidXmlBeansTest$BeanWithChildAndPropNameConflict: Child element name conflicts found with another property.", + }, + }); + } + + private String label, expected; + private Object in; + + public InvalidXmlBeansTest(String label, Object in, String expected) throws Exception { + this.label = label; + this.in = in; + this.expected = expected; + } + + @Test + public void test() { + try { + s1.serialize(in); + fail(label + ": Expected exception didn't occur."); + } catch (Exception e) { + assertEquals(label + ": Wrong error message.", expected, e.getLocalizedMessage()); + } + } + + //-------------------------------------------------------------------------------- + // Test beans + //-------------------------------------------------------------------------------- + + @Xml(format=XmlFormat.ATTR) + public static class BeanWithAttrFormat { + public int f1; + } + + @Xml(format=XmlFormat.ELEMENT) + public static class BeanWithElementFormat { + public int f1; + } + + @Xml(format=XmlFormat.COLLAPSED) + public static class BeanWithCollapsedFormat { + public int f1; + } + + @Xml(format=XmlFormat.MIXED) + public static class BeanWithMixedFormat { + public int f1; + } + + public static class BeanWithMultipleAttrs { + @Xml(format=XmlFormat.ATTRS) + public ObjectMap f1; + @Xml(format=XmlFormat.ATTRS) + public ObjectMap f2; + } + + public static class BeanWithWrongAttrsType { + @Xml(format=XmlFormat.ATTRS) + public ObjectList f1; + } + + public static class BeanWithMulipleElements { + @Xml(format=XmlFormat.ELEMENTS) + public ObjectList f1; + @Xml(format=XmlFormat.ELEMENTS) + public ObjectList f2; + } + + public static class BeanWithWrongElementsType { + @Xml(format=XmlFormat.ELEMENTS) + public ObjectMap f1; + } + + public static class BeanWithMulipleMixed { + @Xml(format=XmlFormat.MIXED) + public ObjectList f1; + @Xml(format=XmlFormat.MIXED) + public ObjectList f2; + } + + public static class BeanWithConflictingChildNames { + @Xml(format=XmlFormat.COLLAPSED, childName="X") + public ObjectList f1; + @Xml(format=XmlFormat.COLLAPSED, childName="X") + public ObjectList f2; + } + + public static class BeanWithElementsAndMixed { + @Xml(format=XmlFormat.ELEMENTS) + public ObjectList f1; + @Xml(format=XmlFormat.MIXED) + public ObjectList f2; + } + + public static class BeanWithElementsAndElement { + @Xml(format=XmlFormat.ELEMENTS) + public ObjectList f1; + @Xml(format=XmlFormat.ELEMENT) + public ObjectList f2; + } + + public static class BeanWithElementsAndDefault { + @Xml(format=XmlFormat.ELEMENTS) + public ObjectList f1; + public ObjectList f2; + } + + public static class BeanWithElementsAndCollapsed { + @Xml(format=XmlFormat.ELEMENTS) + public ObjectList f1; + @Xml(format=XmlFormat.COLLAPSED) + public ObjectList f2; + } + + public static class BeanWithChildAndPropNameConflict { + @Xml(format=XmlFormat.COLLAPSED, childName="f2") + public ObjectList f1; + public ObjectList f2; + } +}
