blob: f1bc5b6ad1dfe737fe0efa65a16d9c122d4dd357 [file] [log] [blame]
// ***************************************************************************************************************************
// * 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.TestUtils.*;
import static org.apache.juneau.xml.annotation.XmlFormat.*;
import static org.junit.Assert.*;
import java.util.*;
import org.apache.juneau.annotation.*;
import org.apache.juneau.utils.*;
import org.apache.juneau.xml.annotation.*;
import org.junit.*;
@SuppressWarnings({"serial"})
public class XmlCollapsedTest {
//====================================================================================================
// testBasic - @Xml.format=COLLAPSED
//====================================================================================================
@Test
public void testBasic() throws Exception {
XmlSerializer s = XmlSerializer.DEFAULT_SQ;
XmlParser p = XmlParser.DEFAULT;
A t = new A();
t.f1 = new AList<String>().append("f1a").append("f1b");
t.f2 = new String[]{"f2a","f2b"};
t.f3 = new AList<String>().append("f3a").append("f3b");
t.f4 = new String[]{"f4a","f4b"};
String xml = s.serialize(t);
assertEquals("<object><f1>f1a</f1><f1>f1b</f1><f2>f2a</f2><f2>f2b</f2><xf3>f3a</xf3><xf3>f3b</xf3><xf4>f4a</xf4><xf4>f4b</xf4></object>", xml);
t = p.parse(xml, A.class);
assertEquals("f1a", t.f1.get(0));
assertEquals("f2a", t.f2[0]);
assertEquals("f3a", t.f3.get(0));
assertEquals("f4a", t.f4[0]);
validateXml(t, s);
}
public static class A {
@Xml(format=COLLAPSED)
public List<String> f1 = new LinkedList<>();
@Xml(format=COLLAPSED)
public String[] f2 = new String[0];
@Xml(format=COLLAPSED,childName="xf3")
public List<String> f3 = new LinkedList<>();
@Xml(format=COLLAPSED,childName="xf4")
public String[] f4 = new String[0];
}
//====================================================================================================
// testUninitializedFields - @Xml.format=COLLAPSED, uninitialized fields.
//====================================================================================================
@Test
public void testUninitializedFields() throws Exception {
XmlSerializer s = XmlSerializer.DEFAULT_SQ;
XmlParser p = XmlParser.DEFAULT;
B t = new B();
t.f1 = new AList<String>().append("f1a").append("f1b");
t.f2 = new String[]{"f2a","f2b"};
t.f3 = new AList<String>().append("f3a").append("f3b");
t.f4 = new String[]{"f4a","f4b"};
String xml = s.serialize(t);
assertEquals("<object><f1>f1a</f1><f1>f1b</f1><f2>f2a</f2><f2>f2b</f2><xf3>f3a</xf3><xf3>f3b</xf3><xf4>f4a</xf4><xf4>f4b</xf4></object>", xml);
t = p.parse(xml, B.class);
assertEquals("f1a", t.f1.get(0));
assertEquals("f2a", t.f2[0]);
assertEquals("f3a", t.f3.get(0));
assertEquals("f4a", t.f4[0]);
validateXml(t, s);
}
public static class B {
@Xml(format=COLLAPSED)
public List<String> f1;
@Xml(format=COLLAPSED)
public String[] f2;
@Xml(format=COLLAPSED,childName="xf3")
public List<String> f3;
@Xml(format=COLLAPSED,childName="xf4")
public String[] f4;
}
//====================================================================================================
// testInitializedFields - @Xml.format=COLLAPSED, initialized fields.
//====================================================================================================
@Test
public void testInitializedFields() throws Exception {
XmlSerializer s = XmlSerializer.DEFAULT_SQ;
XmlParser p = XmlParser.DEFAULT;
C t = new C();
t.f1 = new AList<String>().append("f1b");
t.f2 = new String[]{"f2b"};
t.f3 = new AList<String>().append("f3b");
t.f4 = new String[]{"f4b"};
String xml = s.serialize(t);
assertEquals("<object><f1>f1b</f1><f2>f2b</f2><xf3>f3b</xf3><xf4>f4b</xf4></object>", xml);
// Note that existing fields should be reused and appended to.
t = p.parse(xml, C.class);
assertEquals("f1a", t.f1.get(0));
assertEquals("f1b", t.f1.get(1));
assertEquals("f2a", t.f2[0]);
assertEquals("f2b", t.f2[1]);
assertEquals("f3a", t.f3.get(0));
assertEquals("f3b", t.f3.get(1));
assertEquals("f4a", t.f4[0]);
assertEquals("f4b", t.f4[1]);
validateXml(t, s);
}
public static class C {
@Xml(format=COLLAPSED)
public List<String> f1 = new AList<String>().append("f1a");
@Xml(format=COLLAPSED)
public String[] f2 = {"f2a"};
@Xml(format=COLLAPSED,childName="xf3")
public List<String> f3 = new AList<String>().append("f3a");
@Xml(format=COLLAPSED,childName="xf4")
public String[] f4 = {"f4a"};
}
//====================================================================================================
// testGetters - @Xml.format=COLLAPSED, getters.
//====================================================================================================
@Test
public void testGetters() throws Exception {
XmlSerializer s = XmlSerializer.DEFAULT_SQ;
XmlParser p = XmlParser.DEFAULT;
D t = new D();
t.f1 = new AList<String>().append("f1a");
t.f2 = new String[]{"f2a"};
t.f3 = new AList<String>().append("f3a");
t.f4 = new String[]{"f4a"};
String xml = s.serialize(t);
assertEquals("<object><f1>f1a</f1><f2>f2a</f2><xf3>f3a</xf3><xf4>f4a</xf4></object>", xml);
// Note that existing fields should be reused and appended to.
t = p.parse(xml, D.class);
assertEquals("f1a", t.f1.get(0));
assertEquals("f2a", t.f2[0]);
assertEquals("f3a", t.f3.get(0));
assertEquals("f4a", t.f4[0]);
validateXml(t, s);
}
@Bean(bpi="f1,f2,f3,f4")
public static class D {
private List<String> f1 = new LinkedList<>(), f3 = new LinkedList<>();
private String[] f2, f4;
@Xml(format=COLLAPSED)
public List<String> getF1() {
return f1;
}
@Xml(format=COLLAPSED)
public String[] getF2() {
return f2;
}
public void setF2(String[] f2) {
this.f2 = f2;
}
@Xml(format=COLLAPSED,childName="xf3")
public List<String> getF3() {
return f3;
}
@Xml(format=COLLAPSED,childName="xf4")
public String[] getF4() {
return f4;
}
public void setF4(String[] f4) {
this.f4 = f4;
}
}
//====================================================================================================
// testNullConstructibleCollectionFields - @Xml.format=COLLAPSED, null constructible collection fields.
//====================================================================================================
@Test
public void testNullConstructibleCollectionFields() throws Exception {
XmlSerializer s = XmlSerializer.DEFAULT_SQ;
XmlParser p = XmlParser.DEFAULT;
E t = new E();
t.f1 = new AList<String>().append("f1a");
t.f2 = new AList<String>().append("f2a");
String xml = s.serialize(t);
assertEquals("<object><f1>f1a</f1><xf2>f2a</xf2></object>", xml);
// Note that existing fields should be reused and appended to.
t = p.parse(xml, E.class);
assertEquals("f1a", t.f1.get(0));
assertEquals("f2a", t.f2.get(0));
validateXml(t, s);
}
@Bean(bpi="f1,f2")
public static class E {
private LinkedList<String> f1, f2;
@Xml(format=COLLAPSED)
public LinkedList<String> getF1() {
return f1;
}
public void setF1(LinkedList<String> f1) {
this.f1 = f1;
}
@Xml(format=COLLAPSED,childName="xf2")
public LinkedList<String> getF2() {
return f2;
}
public void setF2(LinkedList<String> f2) {
this.f2 = f2;
}
}
//====================================================================================================
// testElementNameOnElementClass - @Xml.format=COLLAPSED, element name defined on element class.
//====================================================================================================
@Test
public void testElementNameOnElementClass() throws Exception {
XmlSerializer s = XmlSerializer.DEFAULT_SQ;
XmlParser p = XmlParser.DEFAULT;
Object t1 = FA.newInstance(), t2;
String r;
r = s.serialize(t1);
assertEquals("<object><xf1>x1</xf1><xf1>x2</xf1></object>", r);
t2 = p.parse(r, FA.class);
assertEqualObjects(t1, t2);
validateXml(t1, s);
t1 = FB.newInstance();
r = s.serialize(t1);
assertEquals("<object><xf1>x1</xf1><xf1>x2</xf1></object>", r);
t2 = p.parse(r, FB.class);
assertEqualObjects(t1, t2);
validateXml(t1, s);
}
public static class FA {
@Xml(format=COLLAPSED)
public List<F1> f1;
public static FA newInstance() {
FA t = new FA();
t.f1 = new LinkedList<>();
t.f1.add(F1.newInstance("x1"));
t.f1.add(F1.newInstance("x2"));
return t;
}
}
public static class FB {
@Xml(format=COLLAPSED)
public F1[] f1;
public static FB newInstance() {
FB t = new FB();
t.f1 = new F1[]{
F1.newInstance("x1"),
F1.newInstance("x2")
};
return t;
}
}
@Bean(typeName="xf1")
public static class F1 {
@Xml(format=TEXT)
public String text;
public static F1 newInstance(String text) {
F1 t = new F1();
t.text = text;
return t;
}
}
//====================================================================================================
// testElementNameOnElementClassOverridden - @Xml.format=COLLAPSED, element name defined on element class,
// but overridden by @Xml.childName on property.
//====================================================================================================
@Test
public void testElementNameOnElementClassOverridden() throws Exception {
XmlSerializer s = XmlSerializer.DEFAULT_SQ;
XmlParser p = XmlParser.DEFAULT;
G t = G.newInstance(), t2;
String xml = s.serialize(t);
assertEquals("<object><yf1>x1</yf1><yf1>x2</yf1></object>", xml);
// Note that existing fields should be reused and appended to.
t2 = p.parse(xml, G.class);
assertEqualObjects(t, t2);
validateXml(t, s);
}
public static class G {
@Xml(format=COLLAPSED, childName="yf1")
public List<F1> f1;
public static G newInstance() {
G t = new G();
t.f1 = new LinkedList<>();
t.f1.add(F1.newInstance("x1"));
t.f1.add(F1.newInstance("x2"));
return t;
}
}
//====================================================================================================
// testElementNameOnCollectionClass - @Xml.format=COLLAPSED, element name defined on bean class.
//====================================================================================================
@Test
public void testElementNameOnCollectionClass() throws Exception {
XmlSerializer s = XmlSerializer.DEFAULT_SQ;
XmlParser p = XmlParser.DEFAULT;
H t = H.newInstance(), t2;
String xml = s.serialize(t);
assertEquals("<object><xf1>x1</xf1><xf1>x2</xf1></object>", xml);
// Note that existing fields should be reused and appended to.
t2 = p.parse(xml, H.class);
assertEqualObjects(t, t2);
validateXml(t, s);
}
public static class H {
@Xml(format=COLLAPSED)
public H1 f1;
public static H newInstance() {
H t = new H();
t.f1 = new H1();
t.f1.add("x1");
t.f1.add("x2");
return t;
}
}
@Xml(childName="xf1")
public static class H1 extends LinkedList<String> {
}
//====================================================================================================
// testElementNameOnCollectionClassOverridden - @Xml.format=COLLAPSED, element name defined on element class,
// but overridden by @Xml.childName on property.
//====================================================================================================
@Test
public void testElementNameOnCollectionClassOverridden() throws Exception {
XmlSerializer s = XmlSerializer.DEFAULT_SQ;
XmlParser p = XmlParser.DEFAULT;
G t = G.newInstance(), t2;
String xml = s.serialize(t);
assertEquals("<object><yf1>x1</yf1><yf1>x2</yf1></object>", xml);
// Note that existing fields should be reused and appended to.
t2 = p.parse(xml, G.class);
assertEqualObjects(t, t2);
validateXml(t, s);
}
public static class I {
@Xml(format=COLLAPSED, childName="yf1")
public H1 f1;
public static I newInstance() {
I t = new I();
t.f1 = new H1();
t.f1.add("x1");
t.f1.add("x2");
return t;
}
}
}