Skip to content

Commit 0478375

Browse files
committed
Merge branch '2.19'
2 parents 526d72c + 42f0bc3 commit 0478375

File tree

69 files changed

+980
-217
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+980
-217
lines changed
Lines changed: 383 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,383 @@
1+
package tools.jackson.dataformat.xml;
2+
3+
import java.io.*;
4+
import java.nio.charset.StandardCharsets;
5+
import java.util.Arrays;
6+
7+
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
8+
import tools.jackson.core.*;
9+
import tools.jackson.databind.AnnotationIntrospector;
10+
import tools.jackson.databind.type.TypeFactory;
11+
import tools.jackson.dataformat.xml.annotation.JacksonXmlProperty;
12+
import tools.jackson.module.jakarta.xmlbind.JakartaXmlBindAnnotationIntrospector;
13+
14+
import static org.junit.jupiter.api.Assertions.*;
15+
16+
public abstract class XmlTestUtil
17+
{
18+
protected static final String DEFAULT_NEW_LINE;
19+
20+
static {
21+
String newLine = System.getProperty("line.separator");
22+
DEFAULT_NEW_LINE = newLine == null ? "\n" : newLine;
23+
}
24+
25+
@JsonPropertyOrder({ "first", "last", "id" })
26+
protected static class NameBean {
27+
@JacksonXmlProperty(isAttribute=true)
28+
public int age;
29+
public String last, first;
30+
31+
public NameBean() { }
32+
public NameBean(int age, String f, String l) {
33+
this.age = age;
34+
first = f;
35+
last = l;
36+
}
37+
}
38+
39+
/**
40+
* Sample class from Jackson tutorial ("JacksonInFiveMinutes")
41+
*/
42+
public static class FiveMinuteUser {
43+
public enum Gender { MALE, FEMALE };
44+
45+
public static class Name
46+
{
47+
private String _first, _last;
48+
49+
public Name() { }
50+
public Name(String f, String l) {
51+
_first = f;
52+
_last = l;
53+
}
54+
55+
public String getFirst() { return _first; }
56+
public String getLast() { return _last; }
57+
58+
public void setFirst(String s) { _first = s; }
59+
public void setLast(String s) { _last = s; }
60+
61+
@Override
62+
public boolean equals(Object o)
63+
{
64+
if (o == this) return true;
65+
if (o == null || o.getClass() != getClass()) return false;
66+
Name other = (Name) o;
67+
return _first.equals(other._first) && _last.equals(other._last);
68+
}
69+
}
70+
71+
private Gender _gender;
72+
private Name _name;
73+
private boolean _isVerified;
74+
private byte[] _userImage;
75+
76+
public FiveMinuteUser() { }
77+
78+
public FiveMinuteUser(String first, String last, boolean verified, Gender g, byte[] data)
79+
{
80+
_name = new Name(first, last);
81+
_isVerified = verified;
82+
_gender = g;
83+
_userImage = data;
84+
}
85+
86+
public Name getName() { return _name; }
87+
public boolean isVerified() { return _isVerified; }
88+
public Gender getGender() { return _gender; }
89+
public byte[] getUserImage() { return _userImage; }
90+
91+
public void setName(Name n) { _name = n; }
92+
public void setVerified(boolean b) { _isVerified = b; }
93+
public void setGender(Gender g) { _gender = g; }
94+
public void setUserImage(byte[] b) { _userImage = b; }
95+
96+
@Override
97+
public boolean equals(Object o)
98+
{
99+
if (o == this) return true;
100+
if (o == null || o.getClass() != getClass()) return false;
101+
FiveMinuteUser other = (FiveMinuteUser) o;
102+
if (_isVerified != other._isVerified) return false;
103+
if (_gender != other._gender) return false;
104+
if (!_name.equals(other._name)) return false;
105+
byte[] otherImage = other._userImage;
106+
if (otherImage.length != _userImage.length) return false;
107+
for (int i = 0, len = _userImage.length; i < len; ++i) {
108+
if (_userImage[i] != otherImage[i]) {
109+
return false;
110+
}
111+
}
112+
return true;
113+
}
114+
}
115+
116+
protected static class StringBean
117+
{
118+
public String text;
119+
120+
public StringBean() { this("foobar"); }
121+
public StringBean(String s) { text = s; }
122+
123+
@Override
124+
public String toString() {
125+
if (text == null) return "NULL";
126+
return "\""+text+"\"";
127+
}
128+
}
129+
130+
/**
131+
* Simple wrapper around String type, usually to test value
132+
* conversions or wrapping
133+
*/
134+
protected static class StringWrapper {
135+
public String str;
136+
137+
public StringWrapper() { }
138+
public StringWrapper(String value) {
139+
str = value;
140+
}
141+
}
142+
143+
protected static class IntWrapper {
144+
public int i;
145+
146+
public IntWrapper() { }
147+
public IntWrapper(int value) {
148+
i = value;
149+
}
150+
}
151+
152+
public static class Point {
153+
public int x, y;
154+
155+
protected Point() { } // for deser
156+
public Point(int x0, int y0) {
157+
x = x0;
158+
y = y0;
159+
}
160+
161+
@Override
162+
public boolean equals(Object o) {
163+
if (!(o instanceof Point)) {
164+
return false;
165+
}
166+
Point other = (Point) o;
167+
return (other.x == x) && (other.y == y);
168+
}
169+
170+
@Override
171+
public String toString() {
172+
return String.format("[x=%d, y=%d]", x, y);
173+
}
174+
}
175+
176+
/*
177+
/**********************************************************
178+
/* Some sample documents:
179+
/**********************************************************
180+
*/
181+
182+
protected final static int SAMPLE_SPEC_VALUE_WIDTH = 800;
183+
protected final static int SAMPLE_SPEC_VALUE_HEIGHT = 600;
184+
protected final static String SAMPLE_SPEC_VALUE_TITLE = "View from 15th Floor";
185+
protected final static String SAMPLE_SPEC_VALUE_TN_URL = "http://www.example.com/image/481989943";
186+
protected final static int SAMPLE_SPEC_VALUE_TN_HEIGHT = 125;
187+
protected final static String SAMPLE_SPEC_VALUE_TN_WIDTH = "100";
188+
protected final static int SAMPLE_SPEC_VALUE_TN_ID1 = 116;
189+
protected final static int SAMPLE_SPEC_VALUE_TN_ID2 = 943;
190+
protected final static int SAMPLE_SPEC_VALUE_TN_ID3 = 234;
191+
protected final static int SAMPLE_SPEC_VALUE_TN_ID4 = 38793;
192+
193+
protected final static String SAMPLE_DOC_JSON_SPEC =
194+
"{\n"
195+
+" \"Image\" : {\n"
196+
+" \"Width\" : "+SAMPLE_SPEC_VALUE_WIDTH+",\n"
197+
+" \"Height\" : "+SAMPLE_SPEC_VALUE_HEIGHT+","
198+
+"\"Title\" : \""+SAMPLE_SPEC_VALUE_TITLE+"\",\n"
199+
+" \"Thumbnail\" : {\n"
200+
+" \"Url\" : \""+SAMPLE_SPEC_VALUE_TN_URL+"\",\n"
201+
+"\"Height\" : "+SAMPLE_SPEC_VALUE_TN_HEIGHT+",\n"
202+
+" \"Width\" : \""+SAMPLE_SPEC_VALUE_TN_WIDTH+"\"\n"
203+
+" },\n"
204+
+" \"IDs\" : ["+SAMPLE_SPEC_VALUE_TN_ID1+","+SAMPLE_SPEC_VALUE_TN_ID2+","+SAMPLE_SPEC_VALUE_TN_ID3+","+SAMPLE_SPEC_VALUE_TN_ID4+"]\n"
205+
+" }"
206+
+"}"
207+
;
208+
209+
/*
210+
/**********************************************************
211+
/* Construction, factory methods
212+
/**********************************************************
213+
*/
214+
215+
protected XmlTestUtil() {
216+
super();
217+
}
218+
219+
protected XmlFactoryBuilder streamFactoryBuilder() {
220+
return XmlFactory.builder();
221+
}
222+
223+
protected static XmlMapper newMapper() {
224+
return new XmlMapper();
225+
}
226+
227+
protected static XmlMapper.Builder mapperBuilder() {
228+
return XmlMapper.builder();
229+
}
230+
231+
protected static XmlMapper.Builder mapperBuilder(XmlFactory f) {
232+
return XmlMapper.builder(f);
233+
}
234+
235+
protected XmlMapper xmlMapper(boolean useListWrapping)
236+
{
237+
return XmlMapper.builder()
238+
.defaultUseWrapper(useListWrapping)
239+
.build();
240+
}
241+
242+
protected AnnotationIntrospector jakartaXMLBindAnnotationIntrospector() {
243+
return new JakartaXmlBindAnnotationIntrospector();
244+
}
245+
246+
/*
247+
/**********************************************************
248+
/* Additional assertion methods
249+
/**********************************************************
250+
*/
251+
252+
protected void assertToken(JsonToken expToken, JsonToken actToken)
253+
{
254+
if (actToken != expToken) {
255+
fail("Expected token "+expToken+", current token "+actToken);
256+
}
257+
}
258+
259+
protected void assertToken(JsonToken expToken, JsonParser jp)
260+
{
261+
assertToken(expToken, jp.currentToken());
262+
}
263+
264+
/**
265+
* Method that gets textual contents of the current token using
266+
* available methods, and ensures results are consistent, before
267+
* returning them
268+
*/
269+
protected String getAndVerifyText(JsonParser jp)
270+
throws IOException
271+
{
272+
// Ok, let's verify other accessors
273+
int actLen = jp.getStringLength();
274+
char[] ch = jp.getStringCharacters();
275+
String str2 = new String(ch, jp.getStringOffset(), actLen);
276+
String str = jp.getString();
277+
278+
if (str.length() != actLen) {
279+
fail("Internal problem (jp.token == "+jp.currentToken()+"): jp.getText().length() ['"+str+"'] == "+str.length()+"; jp.getTextLength() == "+actLen);
280+
}
281+
assertEquals("String access via getText(), getTextXxx() must be the same", str, str2);
282+
283+
return str;
284+
}
285+
286+
protected void verifyFieldName(JsonParser jp, String expName)
287+
throws IOException
288+
{
289+
assertEquals(expName, jp.getString());
290+
assertEquals(expName, jp.currentName());
291+
}
292+
293+
protected void verifyException(Throwable e, String... matches)
294+
{
295+
String msg = e.getMessage();
296+
String lmsg = (msg == null) ? "" : msg.toLowerCase();
297+
for (String match : matches) {
298+
String lmatch = match.toLowerCase();
299+
if (lmsg.indexOf(lmatch) >= 0) {
300+
return;
301+
}
302+
}
303+
fail("Expected an exception with one of substrings ("+Arrays.asList(matches)+"): got one ("+
304+
e.getClass().getName()+") with message \""+msg+"\"");
305+
}
306+
307+
/*
308+
/**********************************************************
309+
/* Helper methods, other
310+
/**********************************************************
311+
*/
312+
313+
protected static String a2q(String content) {
314+
return content.replace("'", "\"");
315+
}
316+
317+
protected byte[] utf8Bytes(String str) {
318+
return str.getBytes(StandardCharsets.UTF_8);
319+
}
320+
321+
/**
322+
* Helper method that tries to remove unnecessary namespace
323+
* declaration that default JDK XML parser (SJSXP) sees fit
324+
* to add.
325+
*/
326+
protected static String removeSjsxpNamespace(String xml)
327+
{
328+
final String match = " xmlns=\"\"";
329+
int ix = xml.indexOf(match);
330+
if (ix > 0) {
331+
xml = xml.substring(0, ix) + xml.substring(ix+match.length());
332+
}
333+
return xml;
334+
}
335+
336+
protected String readAll(File f) throws IOException
337+
{
338+
StringBuilder sb = new StringBuilder();
339+
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(f), "UTF-8"));
340+
String line;
341+
342+
while ((line = br.readLine()) != null) {
343+
sb.append(line).append("\n");
344+
}
345+
br.close();
346+
return sb.toString();
347+
}
348+
349+
protected byte[] readResource(String ref)
350+
{
351+
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
352+
final byte[] buf = new byte[4000];
353+
354+
InputStream in = getClass().getResourceAsStream(ref);
355+
if (in != null) {
356+
try {
357+
int len;
358+
while ((len = in.read(buf)) > 0) {
359+
bytes.write(buf, 0, len);
360+
}
361+
in.close();
362+
} catch (IOException e) {
363+
throw new RuntimeException("Failed to read resource '"+ref+"': "+e);
364+
}
365+
}
366+
if (bytes.size() == 0) {
367+
throw new IllegalArgumentException("Failed to read resource '"+ref+"': empty resource?");
368+
}
369+
return bytes.toByteArray();
370+
}
371+
372+
public String jaxbSerialized(Object ob, Class<?>... classes) throws Exception
373+
{
374+
StringWriter sw = new StringWriter();
375+
if (classes.length == 0) {
376+
jakarta.xml.bind.JAXB.marshal(ob, sw);
377+
} else {
378+
jakarta.xml.bind.JAXBContext.newInstance(classes).createMarshaller().marshal(ob, sw);
379+
}
380+
sw.close();
381+
return sw.toString();
382+
}
383+
}

0 commit comments

Comments
 (0)