package com.fasterxml.jackson.dataformat.xml.failing;
import java.io.UnsupportedEncodingException;
import java.net.*;
import java.util.*;
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.dataformat.xml.*;
import com.fasterxml.jackson.dataformat.xml.jaxb.XmlJaxbAnnotationIntrospector;
public class Issue37AdapterTest extends XmlTestBase
{
@XmlJavaTypeAdapter(URLEncoderMapDataAdapter.class)
public static class MapData
{
public String key;
public String value;
public MapData() { }
public MapData(String key, String value) {
super();
this.key = key;
this.value = value;
}
}
public static class URLEncoderMapDataAdapter extends XmlAdapter<MapData[], Map<String, String>>
{
public URLEncoderMapDataAdapter() { }
@Override
public MapData[] marshal(Map<String, String> arg0) throws Exception {
MapData[] mapElements = new MapData[arg0.size()];
int i = 0;
for (Map.Entry<String, String> entry : arg0.entrySet()) {
mapElements[i++] = new MapData(encodeKey(entry.getKey()), entry.getValue());
}
return mapElements;
}
@Override
public Map<String, String> unmarshal(MapData[] arg0) throws Exception {
Map<String, String> r = new HashMap<String, String>();
for (MapData mapelement : arg0) {
r.put(decodeKey(mapelement.key), mapelement.value);
}
return r;
}
private final static String ENCODING = "UTF-8";
private String encodeKey(String key) throws UnsupportedEncodingException {
return URLEncoder.encode(key, ENCODING);
}
private String decodeKey(String key) throws UnsupportedEncodingException {
return URLDecoder.decode(key, ENCODING);
}
}
@XmlRootElement(name = "DocWithMapData")
public static class DocWithMapData
{
@XmlJavaTypeAdapter(value = URLEncoderMapDataAdapter.class) // type = MapData[].class)
public Map<String, String> mapDatas;
}
@XmlRootElement(name = "DocWithMapDataSimpleAnnotation")
public static class DocWithMapDataSimpleAnnotation
{
@XmlJavaTypeAdapter(URLEncoderMapDataAdapter.class)
public Map<String, String> mapDatas;
}
private Map<String, String> simpleMapData = singletonMap("key", "value");
private Map<String, String> needEncodingMapData = singletonMap("my/key", "my/value");
private Map<String,String> singletonMap(String a, String b) {
Map<String,String> map = new HashMap<String,String>();
map.put(a,b);
return map;
}
/*
/**********************************************************************
/* Set up
/***********************************************************************
*/
protected XmlMapper _jaxbMapper;
protected XmlMapper _nonJaxbMapper;
@Override
public void setUp() throws Exception
{
super.setUp();
_jaxbMapper = new XmlMapper();
_nonJaxbMapper = new XmlMapper();
// Use JAXB-then-Jackson annotation introspector
AnnotationIntrospector intr =
XmlAnnotationIntrospector.Pair.instance(new XmlJaxbAnnotationIntrospector(TypeFactory.defaultInstance()),
new JacksonAnnotationIntrospector());
_jaxbMapper.setAnnotationIntrospector(intr);
}
/*
/**********************************************************************
/* Unit tests
/**********************************************************************
*/
public void testSimpleKeyMap() throws Exception
{
DocWithMapData bean = new DocWithMapData();
bean.mapDatas = simpleMapData;
assertEquals("<DocWithMapData><mapDatas><key>value</key></mapDatas></DocWithMapData>",
_jaxbMapper.writeValueAsString(bean));
}
public void testNeedEncodingKeyMap() throws Exception
{
DocWithMapData bean = new DocWithMapData();
bean.mapDatas = needEncodingMapData;
String xml = _jaxbMapper.writeValueAsString(bean);
assertEquals("<DocWithMapData><mapDatas><my%2Fkey>my/value</my%2Fkey></mapDatas></DocWithMapData>",
xml);
}
public void testSimpleKeyMapSimpleAnnotation() throws Exception
{
DocWithMapDataSimpleAnnotation bean = new DocWithMapDataSimpleAnnotation();
bean.mapDatas = simpleMapData;
assertEquals(
"<DocWithMapDataSimpleAnnotation><mapDatas><key>value</key></mapDatas></DocWithMapDataSimpleAnnotation>",
_jaxbMapper.writeValueAsString(bean));
}
public void testNeedEncodingKeyMapSimpleAnnotation() throws Exception
{
DocWithMapDataSimpleAnnotation bean = new DocWithMapDataSimpleAnnotation();
bean.mapDatas = needEncodingMapData;
assertEquals(
"<DocWithMapDataSimpleAnnotation><mapDatas><my%2Fkey>my/value</my%2Fkey></mapDatas></DocWithMapDataSimpleAnnotation>",
_jaxbMapper.writeValueAsString(bean));
}
public void testNeedEncodingKeyMap_nonJaxb() throws Exception
{
DocWithMapData bean = new DocWithMapData();
bean.mapDatas = needEncodingMapData;
assertEquals(
"<DocWithMapData><mapDatas><my%2Fkey>my/value</my%2Fkey></mapDatas></DocWithMapData>",
_nonJaxbMapper.writeValueAsString(bean));
}
public void testNeedEncodingKeyMapSimpleAnnotation_nonJaxb() throws Exception
{
DocWithMapDataSimpleAnnotation bean = new DocWithMapDataSimpleAnnotation();
bean.mapDatas = needEncodingMapData;
assertEquals(
"<DocWithMapDataSimpleAnnotation><mapDatas><my%2Fkey>my/value</my%2Fkey></mapDatas></DocWithMapDataSimpleAnnotation>",
_nonJaxbMapper.writeValueAsString(bean));
}
}