Skip to content

Commit

Permalink
Fix #71, problems with XmlMapper.convertValue()
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Aug 15, 2013
1 parent b9e5755 commit a6df5db
Show file tree
Hide file tree
Showing 5 changed files with 284 additions and 36 deletions.
1 change: 1 addition & 0 deletions release-notes/VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ Project: jackson-dataformat-xml
Version: 2.3.0 (xx-xxx-2013)

#38: Support root-level Collection serialization
#71: Fix issues with `XmlMapper.convertValue()`
- Add support for `JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN`
- Improved indentation

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.ser.SerializerFactory;
import com.fasterxml.jackson.databind.ser.DefaultSerializerProvider;
import com.fasterxml.jackson.databind.util.TokenBuffer;
import com.fasterxml.jackson.dataformat.xml.util.StaxUtil;
import com.fasterxml.jackson.dataformat.xml.util.TypeUtil;
import com.fasterxml.jackson.dataformat.xml.util.XmlRootNameLookup;
Expand Down Expand Up @@ -60,25 +61,31 @@ public DefaultSerializerProvider createInstance(SerializationConfig config,
{
return new XmlSerializerProvider(this, config, jsf);
}


@SuppressWarnings("resource")
@Override
public void serializeValue(JsonGenerator jgen, Object value)
throws IOException, JsonProcessingException
{
final ToXmlGenerator xgen = _asXmlGenerator(jgen);
if (value == null) {
_serializeNull(jgen);
_serializeXmlNull(xgen);
return;
}
Class<?> cls = value.getClass();
QName rootName = _rootNameFromConfig();
if (rootName == null) {
rootName = _rootNameLookup.findRootName(cls, _config);
}
_initWithRootName(jgen, rootName);
final boolean asArray = Collection.class.isAssignableFrom(cls) ||
(cls.isArray() && cls != byte[].class);
if (asArray) {
_startRootArray(jgen, rootName);
final Class<?> cls = value.getClass();
final boolean asArray;
if (xgen == null) { // called by convertValue()
asArray = false;
} else {
QName rootName = _rootNameFromConfig();
if (rootName == null) {
rootName = _rootNameLookup.findRootName(cls, _config);
}
_initWithRootName(xgen, rootName);
asArray = TypeUtil.isIndexedType(cls);
if (asArray) {
_startRootArray(jgen, rootName);
}
}

// From super-class implementation
Expand All @@ -100,23 +107,30 @@ public void serializeValue(JsonGenerator jgen, Object value)
jgen.writeEndObject();
}
}


@SuppressWarnings("resource")
@Override
public void serializeValue(JsonGenerator jgen, Object value, JavaType rootType)
throws IOException, JsonProcessingException
{
final ToXmlGenerator xgen = _asXmlGenerator(jgen);
if (value == null) {
_serializeNull(jgen);
_serializeXmlNull(xgen);
return;
}
QName rootName = _rootNameFromConfig();
if (rootName == null) {
rootName = _rootNameLookup.findRootName(rootType, _config);
}
_initWithRootName(jgen, rootName);
final boolean asArray = TypeUtil.isIndexedType(rootType);
if (asArray) {
_startRootArray(jgen, rootName);
final boolean asArray;
if (xgen == null) { // called by convertValue()
asArray = false;
} else {
QName rootName = _rootNameFromConfig();
if (rootName == null) {
rootName = _rootNameLookup.findRootName(rootType, _config);
}
_initWithRootName(xgen, rootName);
asArray = TypeUtil.isIndexedType(rootType);
if (asArray) {
_startRootArray(jgen, rootName);
}
}

final JsonSerializer<Object> ser = findTypedValueSerializer(rootType, true, null);
Expand All @@ -140,23 +154,30 @@ public void serializeValue(JsonGenerator jgen, Object value, JavaType rootType)
}

// @since 2.1
@SuppressWarnings("resource")
@Override
public void serializeValue(JsonGenerator jgen, Object value, JavaType rootType,
JsonSerializer<Object> ser)
throws IOException, JsonGenerationException
{
final ToXmlGenerator xgen = _asXmlGenerator(jgen);
if (value == null) {
_serializeNull(jgen);
_serializeXmlNull(xgen);
return;
}
QName rootName = _rootNameFromConfig();
if (rootName == null) {
rootName = _rootNameLookup.findRootName(rootType, _config);
}
_initWithRootName(jgen, rootName);
final boolean asArray = TypeUtil.isIndexedType(rootType);
if (asArray) {
_startRootArray(jgen, rootName);
final boolean asArray;
if (xgen == null) { // called by convertValue()
asArray = false;
} else {
QName rootName = _rootNameFromConfig();
if (rootName == null) {
rootName = _rootNameLookup.findRootName(rootType, _config);
}
_initWithRootName(xgen, rootName);
asArray = TypeUtil.isIndexedType(rootType);
if (asArray) {
_startRootArray(jgen, rootName);
}
}
if (ser == null) {
ser = findTypedValueSerializer(rootType, true, null);
Expand Down Expand Up @@ -187,18 +208,16 @@ protected void _startRootArray(JsonGenerator jgen, QName rootName)
((ToXmlGenerator) jgen).writeFieldName("item");
}

@Override
protected void _serializeNull(JsonGenerator jgen)
protected void _serializeXmlNull(ToXmlGenerator jgen)
throws IOException, JsonProcessingException
{
_initWithRootName(jgen, ROOT_NAME_FOR_NULL);
super.serializeValue(jgen, null);
}

protected void _initWithRootName(JsonGenerator jgen, QName rootName)
protected void _initWithRootName(ToXmlGenerator xgen, QName rootName)
throws IOException, JsonProcessingException
{
ToXmlGenerator xgen = (ToXmlGenerator) jgen;
/* 28-Nov-2012, tatu: We should only initialize the root
* name if no name has been set, as per [Issue#42],
* to allow for custom serializers to work.
Expand Down Expand Up @@ -229,4 +248,19 @@ protected QName _rootNameFromConfig()
String name = _config.getRootName();
return (name == null) ? null : new QName(name);
}

protected ToXmlGenerator _asXmlGenerator(JsonGenerator jgen)
throws JsonMappingException
{
// [Issue#71]: When converting, we actually get TokenBuffer, which is fine
if (!(jgen instanceof ToXmlGenerator)) {
// but verify
if (!(jgen instanceof TokenBuffer)) {
throw new JsonMappingException("XmlMapper does not with generators of type other than ToXmlGenerator; got: "
+jgen.getClass().getName());
}
return null;
}
return (ToXmlGenerator) jgen;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.fasterxml.jackson.dataformat.xml.util;

import java.util.Collection;
import java.util.Map;

import com.fasterxml.jackson.databind.JavaType;
Expand Down Expand Up @@ -28,4 +29,8 @@ public static boolean isIndexedType(JavaType type)
return false;
}

public static boolean isIndexedType(Class<?> cls)
{
return (cls.isArray() && cls != byte[].class) || Collection.class.isAssignableFrom(cls);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -164,14 +164,21 @@ public IntWrapper(int value) {

/*
/**********************************************************
/* Construction
/* 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
Expand Down
Loading

0 comments on commit a6df5db

Please sign in to comment.