1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.http.converter.xml;
18
19 import java.lang.reflect.Type;
20 import java.util.Collection;
21 import java.util.List;
22 import java.util.Set;
23 import javax.xml.bind.annotation.XmlAttribute;
24 import javax.xml.bind.annotation.XmlElement;
25 import javax.xml.bind.annotation.XmlRootElement;
26 import javax.xml.bind.annotation.XmlType;
27 import javax.xml.stream.XMLInputFactory;
28
29 import org.junit.Before;
30 import org.junit.Test;
31
32 import org.springframework.core.ParameterizedTypeReference;
33 import org.springframework.core.io.ClassPathResource;
34 import org.springframework.core.io.Resource;
35 import org.springframework.http.MockHttpInputMessage;
36
37 import static org.junit.Assert.*;
38
39
40
41
42
43
44 public class Jaxb2CollectionHttpMessageConverterTests {
45
46 private Jaxb2CollectionHttpMessageConverter<?> converter;
47
48 private Type rootElementListType;
49
50 private Type rootElementSetType;
51
52 private Type typeListType;
53
54 private Type typeSetType;
55
56
57 @Before
58 public void setUp() {
59 converter = new Jaxb2CollectionHttpMessageConverter<Collection<Object>>();
60 rootElementListType = new ParameterizedTypeReference<List<RootElement>>() {}.getType();
61 rootElementSetType = new ParameterizedTypeReference<Set<RootElement>>() {}.getType();
62 typeListType = new ParameterizedTypeReference<List<TestType>>() {}.getType();
63 typeSetType = new ParameterizedTypeReference<Set<TestType>>() {}.getType();
64 }
65
66 @Test
67 public void canRead() throws Exception {
68 assertTrue(converter.canRead(rootElementListType, null, null));
69 assertTrue(converter.canRead(rootElementSetType, null, null));
70 assertTrue(converter.canRead(typeSetType, null, null));
71 }
72
73 @Test
74 @SuppressWarnings("unchecked")
75 public void readXmlRootElementList() throws Exception {
76 String content = "<list><rootElement><type s=\"1\"/></rootElement><rootElement><type s=\"2\"/></rootElement></list>";
77 MockHttpInputMessage inputMessage = new MockHttpInputMessage(content.getBytes("UTF-8"));
78
79 List<RootElement> result = (List<RootElement>) converter.read(rootElementListType, null, inputMessage);
80
81 assertEquals("Invalid result", 2, result.size());
82 assertEquals("Invalid result", "1", result.get(0).type.s);
83 assertEquals("Invalid result", "2", result.get(1).type.s);
84 }
85
86 @Test
87 @SuppressWarnings("unchecked")
88 public void readXmlRootElementSet() throws Exception {
89 String content = "<set><rootElement><type s=\"1\"/></rootElement><rootElement><type s=\"2\"/></rootElement></set>";
90 MockHttpInputMessage inputMessage = new MockHttpInputMessage(content.getBytes("UTF-8"));
91
92 Set<RootElement> result = (Set<RootElement>) converter.read(rootElementSetType, null, inputMessage);
93
94 assertEquals("Invalid result", 2, result.size());
95 assertTrue("Invalid result", result.contains(new RootElement("1")));
96 assertTrue("Invalid result", result.contains(new RootElement("2")));
97 }
98
99 @Test
100 @SuppressWarnings("unchecked")
101 public void readXmlTypeList() throws Exception {
102 String content = "<list><foo s=\"1\"/><bar s=\"2\"/></list>";
103 MockHttpInputMessage inputMessage = new MockHttpInputMessage(content.getBytes("UTF-8"));
104
105 List<TestType> result = (List<TestType>) converter.read(typeListType, null, inputMessage);
106
107 assertEquals("Invalid result", 2, result.size());
108 assertEquals("Invalid result", "1", result.get(0).s);
109 assertEquals("Invalid result", "2", result.get(1).s);
110 }
111
112 @Test
113 @SuppressWarnings("unchecked")
114 public void readXmlTypeSet() throws Exception {
115 String content = "<set><foo s=\"1\"/><bar s=\"2\"/></set>";
116 MockHttpInputMessage inputMessage = new MockHttpInputMessage(content.getBytes("UTF-8"));
117
118 Set<TestType> result = (Set<TestType>) converter.read(typeSetType, null, inputMessage);
119
120 assertEquals("Invalid result", 2, result.size());
121 assertTrue("Invalid result", result.contains(new TestType("1")));
122 assertTrue("Invalid result", result.contains(new TestType("2")));
123 }
124
125 @Test
126 @SuppressWarnings("unchecked")
127 public void readXmlRootElementExternalEntityDisabled() throws Exception {
128
129 Resource external = new ClassPathResource("external.txt", getClass());
130 String content = "<!DOCTYPE root [" +
131 " <!ELEMENT external ANY >\n" +
132 " <!ENTITY ext SYSTEM \"" + external.getURI() + "\" >]>" +
133 " <list><rootElement><type s=\"1\"/><external>&ext;</external></rootElement></list>";
134 MockHttpInputMessage inputMessage = new MockHttpInputMessage(content.getBytes("UTF-8"));
135
136 Collection<RootElement> result = converter.read(rootElementListType, null, inputMessage);
137 assertEquals(1, result.size());
138 assertEquals("", result.iterator().next().external);
139 }
140
141 @Test
142 @SuppressWarnings("unchecked")
143 public void readXmlRootElementExternalEntityEnabled() throws Exception {
144
145 Resource external = new ClassPathResource("external.txt", getClass());
146 String content = "<!DOCTYPE root [" +
147 " <!ELEMENT external ANY >\n" +
148 " <!ENTITY ext SYSTEM \"" + external.getURI() + "\" >]>" +
149 " <list><rootElement><type s=\"1\"/><external>&ext;</external></rootElement></list>";
150 MockHttpInputMessage inputMessage = new MockHttpInputMessage(content.getBytes("UTF-8"));
151
152 Jaxb2CollectionHttpMessageConverter<?> c = new Jaxb2CollectionHttpMessageConverter<Collection<Object>>() {
153 @Override
154 protected XMLInputFactory createXmlInputFactory() {
155 XMLInputFactory inputFactory = XMLInputFactory.newInstance();
156 inputFactory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, true);
157 return inputFactory;
158 }
159 };
160
161 Collection<RootElement> result = c.read(rootElementListType, null, inputMessage);
162 assertEquals(1, result.size());
163 assertEquals("Foo Bar", result.iterator().next().external);
164 }
165
166
167 @XmlRootElement
168 public static class RootElement {
169
170 public RootElement() {
171 }
172
173 public RootElement(String s) {
174 this.type = new TestType(s);
175 }
176
177 @XmlElement
178 public TestType type = new TestType();
179
180 @XmlElement(required=false)
181 public String external;
182
183 @Override
184 public boolean equals(Object o) {
185 if (this == o) {
186 return true;
187 }
188 if (o instanceof RootElement) {
189 RootElement other = (RootElement) o;
190 return this.type.equals(other.type);
191 }
192 return false;
193 }
194
195 @Override
196 public int hashCode() {
197 return type.hashCode();
198 }
199 }
200
201 @XmlType
202 public static class TestType {
203
204 public TestType() {
205 }
206
207 public TestType(String s) {
208 this.s = s;
209 }
210
211 @XmlAttribute
212 public String s = "Hello World";
213
214 @Override
215 public boolean equals(Object o) {
216 if (this == o) {
217 return true;
218 }
219 if (o instanceof TestType) {
220 TestType other = (TestType) o;
221 return this.s.equals(other.s);
222 }
223 return false;
224 }
225
226 @Override
227 public int hashCode() {
228 return s.hashCode();
229 }
230 }
231
232 }