package com.fasterxml.jackson.dataformat.xml; import java.io.*; import java.util.Arrays; import junit.framework.TestCase; import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; public abstract class XmlTestBase extends TestCase { @JsonPropertyOrder({ "first", "last", "id" }) protected static class NameBean { @JacksonXmlProperty(isAttribute=true) public int age; public String last, first; public NameBean() { } public NameBean(int age, String f, String l) { this.age = age; first = f; last = l; } } /** * Sample class from Jackson tutorial ("JacksonInFiveMinutes") */ public static class FiveMinuteUser { public enum Gender { MALE, FEMALE }; public static class Name { private String _first, _last; public Name() { } public Name(String f, String l) { _first = f; _last = l; } public String getFirst() { return _first; } public String getLast() { return _last; } public void setFirst(String s) { _first = s; } public void setLast(String s) { _last = s; } @Override public boolean equals(Object o) { if (o == this) return true; if (o == null || o.getClass() != getClass()) return false; Name other = (Name) o; return _first.equals(other._first) && _last.equals(other._last); } } private Gender _gender; private Name _name; private boolean _isVerified; private byte[] _userImage; public FiveMinuteUser() { } public FiveMinuteUser(String first, String last, boolean verified, Gender g, byte[] data) { _name = new Name(first, last); _isVerified = verified; _gender = g; _userImage = data; } public Name getName() { return _name; } public boolean isVerified() { return _isVerified; } public Gender getGender() { return _gender; } public byte[] getUserImage() { return _userImage; } public void setName(Name n) { _name = n; } public void setVerified(boolean b) { _isVerified = b; } public void setGender(Gender g) { _gender = g; } public void setUserImage(byte[] b) { _userImage = b; } @Override public boolean equals(Object o) { if (o == this) return true; if (o == null || o.getClass() != getClass()) return false; FiveMinuteUser other = (FiveMinuteUser) o; if (_isVerified != other._isVerified) return false; if (_gender != other._gender) return false; if (!_name.equals(other._name)) return false; byte[] otherImage = other._userImage; if (otherImage.length != _userImage.length) return false; for (int i = 0, len = _userImage.length; i < len; ++i) { if (_userImage[i] != otherImage[i]) { return false; } } return true; } } protected static class StringBean { public String text; public StringBean() { this("foobar"); } public StringBean(String s) { text = s; } @Override public String toString() { if (text == null) return "NULL"; return "\""+text+"\""; } } /** * Simple wrapper around String type, usually to test value * conversions or wrapping */ protected static class StringWrapper { public String str; public StringWrapper() { } public StringWrapper(String value) { str = value; } } protected static class IntWrapper { public int i; public IntWrapper() { } public IntWrapper(int value) { i = value; } } /* /********************************************************** /* Some sample documents: /********************************************************** */ protected final static int SAMPLE_SPEC_VALUE_WIDTH = 800; protected final static int SAMPLE_SPEC_VALUE_HEIGHT = 600; protected final static String SAMPLE_SPEC_VALUE_TITLE = "View from 15th Floor"; protected final static String SAMPLE_SPEC_VALUE_TN_URL = "http://www.example.com/image/481989943"; protected final static int SAMPLE_SPEC_VALUE_TN_HEIGHT = 125; protected final static String SAMPLE_SPEC_VALUE_TN_WIDTH = "100"; protected final static int SAMPLE_SPEC_VALUE_TN_ID1 = 116; protected final static int SAMPLE_SPEC_VALUE_TN_ID2 = 943; protected final static int SAMPLE_SPEC_VALUE_TN_ID3 = 234; protected final static int SAMPLE_SPEC_VALUE_TN_ID4 = 38793; protected final static String SAMPLE_DOC_JSON_SPEC = "{\n" +" \"Image\" : {\n" +" \"Width\" : "+SAMPLE_SPEC_VALUE_WIDTH+",\n" +" \"Height\" : "+SAMPLE_SPEC_VALUE_HEIGHT+"," +"\"Title\" : \""+SAMPLE_SPEC_VALUE_TITLE+"\",\n" +" \"Thumbnail\" : {\n" +" \"Url\" : \""+SAMPLE_SPEC_VALUE_TN_URL+"\",\n" +"\"Height\" : "+SAMPLE_SPEC_VALUE_TN_HEIGHT+",\n" +" \"Width\" : \""+SAMPLE_SPEC_VALUE_TN_WIDTH+"\"\n" +" },\n" +" \"IDs\" : ["+SAMPLE_SPEC_VALUE_TN_ID1+","+SAMPLE_SPEC_VALUE_TN_ID2+","+SAMPLE_SPEC_VALUE_TN_ID3+","+SAMPLE_SPEC_VALUE_TN_ID4+"]\n" +" }" +"}" ; /* /********************************************************** /* Construction, factory methods /********************************************************** */ protected XmlTestBase() { super(); } protected XmlMapper xmlMapper(boolean useListWrapping) { JacksonXmlModule module = new JacksonXmlModule(); module.setDefaultUseWrapper(useListWrapping); return new XmlMapper(module); } /* /********************************************************** /* Additional assertion methods /********************************************************** */ protected void assertToken(JsonToken expToken, JsonToken actToken) { if (actToken != expToken) { fail("Expected token "+expToken+", current token "+actToken); } } protected void assertToken(JsonToken expToken, JsonParser jp) { assertToken(expToken, jp.getCurrentToken()); } /** * Method that gets textual contents of the current token using * available methods, and ensures results are consistent, before * returning them */ protected String getAndVerifyText(JsonParser jp) throws IOException, JsonParseException { // Ok, let's verify other accessors int actLen = jp.getTextLength(); char[] ch = jp.getTextCharacters(); String str2 = new String(ch, jp.getTextOffset(), actLen); String str = jp.getText(); if (str.length() != actLen) { fail("Internal problem (jp.token == "+jp.getCurrentToken()+"): jp.getText().length() ['"+str+"'] == "+str.length()+"; jp.getTextLength() == "+actLen); } assertEquals("String access via getText(), getTextXxx() must be the same", str, str2); return str; } protected void verifyFieldName(JsonParser jp, String expName) throws IOException { assertEquals(expName, jp.getText()); assertEquals(expName, jp.getCurrentName()); } protected void verifyException(Throwable e, String... matches) { String msg = e.getMessage(); String lmsg = (msg == null) ? "" : msg.toLowerCase(); for (String match : matches) { String lmatch = match.toLowerCase(); if (lmsg.indexOf(lmatch) >= 0) { return; } } fail("Expected an exception with one of substrings ("+Arrays.asList(matches)+"): got one with message \""+msg+"\""); } /* /********************************************************** /* Helper methods, other /********************************************************** */ protected static String aposToQuotes(String json) { return json.replace("'", "\""); } protected byte[] utf8Bytes(String str) { try { return str.getBytes("UTF-8"); } catch (IOException e) { throw new IllegalArgumentException(e); } } /** * Helper method that tries to remove unnecessary namespace * declaration that default JDK XML parser (SJSXP) sees fit * to add. */ protected static String removeSjsxpNamespace(String xml) { final String match = " xmlns=\"\""; int ix = xml.indexOf(match); if (ix > 0) { xml = xml.substring(0, ix) + xml.substring(ix+match.length()); } return xml; } protected String readAll(File f) throws IOException { StringBuilder sb = new StringBuilder(); BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(f), "UTF-8")); String line; while ((line = br.readLine()) != null) { sb.append(line).append("\n"); } br.close(); return sb.toString(); } public String jaxbSerialized(Object ob, Class<?>... classes) throws Exception { StringWriter sw = new StringWriter(); if (classes.length == 0) { javax.xml.bind.JAXB.marshal(ob, sw); } else { javax.xml.bind.JAXBContext.newInstance(classes).createMarshaller().marshal(ob, sw); } sw.close(); return sw.toString(); } }