View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.juneau.xml;
18  
19  import static org.apache.juneau.TestUtils.*;
20  import static org.apache.juneau.xml.annotation.XmlFormat.*;
21  import static org.junit.jupiter.api.Assertions.*;
22  
23  import java.io.*;
24  
25  import org.apache.juneau.*;
26  import org.apache.juneau.annotation.*;
27  import org.apache.juneau.xml.annotation.*;
28  import org.junit.jupiter.api.*;
29  
30  class XmlContent_Test extends TestBase {
31  
32  	//-----------------------------------------------------------------------------------------------------------------
33  	// Test beans with @Xml(format=CONTENT)
34  	//-----------------------------------------------------------------------------------------------------------------
35  	@Test void a01_contentFormat() throws Exception {
36  		var t = A.newInstance();
37  		var s1 = XmlSerializer.DEFAULT_SQ.copy().keepNullProperties().build();
38  		var s2 = XmlSerializer.create().sq().ws().keepNullProperties().build();
39  		var p = XmlParser.DEFAULT;
40  
41  		//-------------------------------------------------------------------------------------------------------------
42  		// Null
43  		//-------------------------------------------------------------------------------------------------------------
44  		t.f2 = null;
45  
46  		var sw = new StringWriter();
47  		s1.serialize(t, sw);
48  		var r = sw.toString();
49  		assertEquals("<A f1='f1' nil='true'></A>", r);
50  		var t2 = p.parse(r, A.class);
51  		assertEquals(json(t2), json(t));
52  
53  		sw = new StringWriter();
54  		s2.serialize(t, sw);
55  		r = sw.toString();
56  		assertEquals("<A f1='f1' nil='true'></A>\n", r);
57  		t2 = p.parse(r, A.class);
58  		assertEquals(json(t2), json(t));
59  
60  		//-------------------------------------------------------------------------------------------------------------
61  		// Normal text
62  		//-------------------------------------------------------------------------------------------------------------
63  		t.f2 = "foobar";
64  
65  		r = s1.serialize(t);
66  		assertEquals("<A f1='f1'>foobar</A>", r);
67  		t2 = p.parse(r, A.class);
68  		assertEquals(json(t2), json(t));
69  
70  		r = s2.serialize(t);
71  		assertEquals("<A f1='f1'>foobar</A>\n", r);
72  		t2 = p.parse(r, A.class);
73  		assertEquals(json(t2), json(t));
74  
75  		//-------------------------------------------------------------------------------------------------------------
76  		// Special characters
77  		//-------------------------------------------------------------------------------------------------------------
78  		t.f2 = "~!@#$%^&*()_+`-={}|[]\\:\";'<>?,.\n\r\t\b";
79  
80  		r = s1.serialize(t);
81  		assertEquals("<A f1='f1'>~!@#$%^&amp;*()_+`-={}|[]\\:\";'&lt;&gt;?,.&#x000a;&#x000d;&#x0009;_x0008_</A>", r);
82  		t2 = p.parse(r, A.class);
83  		assertEquals(json(t2), json(t));
84  
85  		r = s2.serialize(t);
86  		assertEquals("<A f1='f1'>~!@#$%^&amp;*()_+`-={}|[]\\:\";'&lt;&gt;?,.&#x000a;&#x000d;&#x0009;_x0008_</A>\n", r);
87  		t2 = p.parse(r, A.class);
88  		assertEquals(json(t2), json(t));
89  
90  		//-------------------------------------------------------------------------------------------------------------
91  		// Leading spaces
92  		//-------------------------------------------------------------------------------------------------------------
93  		t.f2 = "  foobar";
94  
95  		r = s1.serialize(t);
96  		assertEquals("<A f1='f1'>_x0020_ foobar</A>", r);
97  		t2 = p.parse(r, A.class);
98  		assertEquals(json(t2), json(t));
99  
100 		r = s2.serialize(t);
101 		assertEquals("<A f1='f1'>_x0020_ foobar</A>\n", r);
102 		t2 = p.parse(r, A.class);
103 		assertEquals(json(t2), json(t));
104 
105 		//-------------------------------------------------------------------------------------------------------------
106 		// Trailing spaces
107 		//-------------------------------------------------------------------------------------------------------------
108 		t.f2 = "foobar  ";
109 
110 		r = s1.serialize(t);
111 		assertEquals("<A f1='f1'>foobar _x0020_</A>", r);
112 		t2 = p.parse(r, A.class);
113 		assertEquals(json(t2), json(t));
114 
115 		r = s2.serialize(t);
116 		assertEquals("<A f1='f1'>foobar _x0020_</A>\n", r);
117 		t2 = p.parse(r, A.class);
118 		assertEquals(json(t2), json(t));
119 	}
120 
121 	@Bean(typeName="A")
122 	public static class A {
123 		@Xml(format=ATTR) public String f1;
124 		@Xml(format=TEXT) public String f2;
125 
126 		public static A newInstance() {
127 			var t = new A();
128 			t.f1 = "f1";
129 			t.f2 = null;
130 			return t;
131 		}
132 	}
133 
134 	//-----------------------------------------------------------------------------------------------------------------
135 	// Test beans with @Xml(format=MIXED)
136 	//-----------------------------------------------------------------------------------------------------------------
137 	@Test void a02_xmlMixed() throws Exception {
138 		var t = B.newInstance();
139 		var s1 = XmlSerializer.DEFAULT_SQ.copy().keepNullProperties().build();
140 		var s2 = XmlSerializer.create().sq().ws().keepNullProperties().build();
141 		var p = XmlParser.DEFAULT;
142 		var sw = new StringWriter();
143 
144 		//-------------------------------------------------------------------------------------------------------------
145 		// Null
146 		//-------------------------------------------------------------------------------------------------------------
147 		t.f2 = null;
148 
149 		s1.serialize(t, sw);
150 		var r = sw.toString();
151 		assertEquals("<A f1='f1' nil='true'></A>", r);
152 		var t2 = p.parse(r, B.class);
153 		assertEquals(json(t2), json(t));
154 
155 		sw = new StringWriter();
156 		s2.serialize(t, sw);
157 		r = sw.toString();
158 		assertEquals("<A f1='f1' nil='true'></A>\n", r);
159 		t2 = p.parse(r, B.class);
160 		assertEquals(json(t2), json(t));
161 
162 		//-------------------------------------------------------------------------------------------------------------
163 		// Normal text
164 		//-------------------------------------------------------------------------------------------------------------
165 		t.f2 = "foobar";
166 
167 		r = s1.serialize(t);
168 		assertEquals("<A f1='f1'>foobar</A>", r);
169 		t2 = p.parse(r, B.class);
170 		assertEquals(json(t2), json(t));
171 
172 		r = s2.serialize(t);
173 		assertEquals("<A f1='f1'>foobar</A>\n", r);
174 		t2 = p.parse(r, B.class);
175 		assertEquals(json(t2), json(t));
176 
177 		//-------------------------------------------------------------------------------------------------------------
178 		// Normal XML
179 		//-------------------------------------------------------------------------------------------------------------
180 		t.f2 = "<xxx>foobar<yyy>baz</yyy>foobar</xxx>";
181 
182 		r = s1.serialize(t);
183 		assertEquals("<A f1='f1'>&lt;xxx&gt;foobar&lt;yyy&gt;baz&lt;/yyy&gt;foobar&lt;/xxx&gt;</A>", r);
184 		t2 = p.parse(r, B.class);
185 		assertEquals(json(t2), json(t));
186 
187 		r = s2.serialize(t);
188 		assertEquals("<A f1='f1'>&lt;xxx&gt;foobar&lt;yyy&gt;baz&lt;/yyy&gt;foobar&lt;/xxx&gt;</A>\n", r);
189 		t2 = p.parse(r, B.class);
190 		assertEquals(json(t2), json(t));
191 
192 		//-------------------------------------------------------------------------------------------------------------
193 		// Normal XML with leading and trailing space
194 		//-------------------------------------------------------------------------------------------------------------
195 		t.f2 = "  <xxx>foobar<yyy>baz</yyy>foobar</xxx>  ";
196 
197 		r = s1.serialize(t);
198 		assertEquals("<A f1='f1'>_x0020_ &lt;xxx&gt;foobar&lt;yyy&gt;baz&lt;/yyy&gt;foobar&lt;/xxx&gt; _x0020_</A>", r);
199 		t2 = p.parse(r, B.class);
200 		assertEquals(json(t2), json(t));
201 
202 		r = s2.serialize(t);
203 		assertEquals("<A f1='f1'>_x0020_ &lt;xxx&gt;foobar&lt;yyy&gt;baz&lt;/yyy&gt;foobar&lt;/xxx&gt; _x0020_</A>\n", r);
204 		t2 = p.parse(r, B.class);
205 		assertEquals(json(t2), json(t));
206 
207 		//-------------------------------------------------------------------------------------------------------------
208 		// XML with attributes
209 		//-------------------------------------------------------------------------------------------------------------
210 		t.f2 = "<xxx x=\"x\">foobar</xxx>";
211 
212 		r = s1.serialize(t);
213 		assertEquals("<A f1='f1'>&lt;xxx x=\"x\"&gt;foobar&lt;/xxx&gt;</A>", r);
214 		t2 = p.parse(r, B.class);
215 		assertEquals(json(t2), json(t));
216 
217 		r = s2.serialize(t);
218 		assertEquals("<A f1='f1'>&lt;xxx x=\"x\"&gt;foobar&lt;/xxx&gt;</A>\n", r);
219 		t2 = p.parse(r, B.class);
220 		assertEquals(json(t2), json(t));
221 
222 		//-------------------------------------------------------------------------------------------------------------
223 		// XML with embedded entities
224 		//-------------------------------------------------------------------------------------------------------------
225 		t.f2 = "<xxx x=\"x\">foo&lt;&gt;bar</xxx>";
226 
227 		r = s1.serialize(t);
228 		assertEquals("<A f1='f1'>&lt;xxx x=\"x\"&gt;foo&amp;lt;&amp;gt;bar&lt;/xxx&gt;</A>", r);
229 		t2 = p.parse(r, B.class);
230 		assertEquals(json(t2), json(t));
231 
232 		r = s2.serialize(t);
233 		assertEquals("<A f1='f1'>&lt;xxx x=\"x\"&gt;foo&amp;lt;&amp;gt;bar&lt;/xxx&gt;</A>\n", r);
234 		t2 = p.parse(r, B.class);
235 		assertEquals(json(t2), json(t));
236 	}
237 
238 	@Bean(typeName="A")
239 	public static class B {
240 		@Xml(format=ATTR) public String f1;
241 		@Xml(format=TEXT) public String f2;
242 
243 		public static B newInstance() {
244 			var t = new B();
245 			t.f1 = "f1";
246 			t.f2 = null;
247 			return t;
248 		}
249 	}
250 }