Skip to content

Commit

Permalink
Fixed #539 in master (for 2.5.0) -- slightly risky change so can't ea…
Browse files Browse the repository at this point in the history
…sily backport unfortunately.
  • Loading branch information
cowtowncoder committed Sep 18, 2014
1 parent f95a927 commit 152aabb
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 29 deletions.
3 changes: 3 additions & 0 deletions release-notes/VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ Version: 2.5.0 (xx-xxx-2014)
#521: Keep bundle annotations, prevent problems with recursive annotation
types
(reported by tea-dragon@github)
#539: Problem with post-procesing of "empty bean" serializer; was not calling
'BeanSerializerModifier.modifySerializer()` for empty beans
(reported by Fabien R, fabienrenaud@github)
#543: Problem resolving self-referential recursive types
(reported by ahgittin@github)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,17 @@ public JsonSerializer<Object> getUnknownTypeSerializer(Class<?> unknownType) {
return _unknownTypeSerializer;
}

/**
* Helper method called to see if given serializer is considered to be
* something returned by {@link #getUnknownTypeSerializer}, that is, something
* for which no regular serializer was found or constructed.
*
* @since 2.5
*/
public boolean isUnknownTypeSerializer(JsonSerializer<?> ser) {
return (ser == _unknownTypeSerializer) || (ser == null);
}

/*
/**********************************************************
/* Methods for creating instances based on annotations
Expand Down Expand Up @@ -987,19 +998,26 @@ protected void _reportIncompatibleRootType(Object value, JavaType rootType)
* @return Serializer if one can be found, null if not.
*/
protected JsonSerializer<Object> _findExplicitUntypedSerializer(Class<?> runtimeType)
throws JsonMappingException
throws JsonMappingException
{
// Fast lookup from local lookup thingy works?
JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(runtimeType);
if (ser != null) {
return ser;
}
// If not, maybe shared map already has it?
ser = _serializerCache.untypedValueSerializer(runtimeType);
if (ser != null) {
return ser;
if (ser == null) {
// If not, maybe shared map already has it?
ser = _serializerCache.untypedValueSerializer(runtimeType);
if (ser == null) {
ser = _createAndCacheUntypedSerializer(runtimeType);
/* 18-Sep-2014, tatu: This is unfortunate patch over related change
* that pushes creation of "unknown type" serializer deeper down
* in BeanSerializerFactory; as a result, we need to "undo" creation
* here.
*/
if (isUnknownTypeSerializer(ser)) {
return null;
}
}
}
return _createAndCacheUntypedSerializer(runtimeType);
return ser;
}

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,12 @@ protected JsonSerializer<?> _createSerializer2(SerializerProvider prov,
// Finally: maybe we can still deal with it as an implementation of some basic JDK interface?
if (ser == null) {
ser = findSerializerByAddonType(config, type, beanDesc, staticTyping);
// 18-Sep-2014, tatu: Actually, as per [jackson-databind#539], need to get
// 'unknown' serializer assigned earlier, here, so that it gets properly
// post-processed
if (ser == null) {
ser = prov.getUnknownTypeSerializer(beanDesc.getBeanClass());
}
}
}
}
Expand Down Expand Up @@ -403,14 +409,10 @@ protected JsonSerializer<Object> constructBeanSerializer(SerializerProvider prov

JsonSerializer<Object> ser = (JsonSerializer<Object>) builder.build();

/* However, after all modifications: no properties, no serializer
* (note; as per [JACKSON-670], check was moved later on from an earlier location)
*/
if (ser == null) {
/* 27-Nov-2009, tatu: Except that as per [JACKSON-201], we are
* ok with that as long as it has a recognized class annotation
* (which may come from a mix-in too)
*/
// If we get this far, there were no properties found, so no regular BeanSerializer
// would be constructed. But, couple of exceptions.
// First: if there are known annotations, just create 'empty bean' serializer
if (beanDesc.hasKnownClassAnnotations()) {
return builder.createDummy();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.core.*;

import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.introspect.AnnotatedField;
import com.fasterxml.jackson.databind.introspect.POJOPropertyBuilder;
Expand All @@ -26,17 +25,11 @@
@SuppressWarnings("serial")
public class TestBeanSerializer extends BaseMapTest
{
/*
/********************************************************
/* Helper types
/********************************************************
*/

static class ModuleImpl extends SimpleModule
static class SerializerModifierModule extends SimpleModule
{
protected BeanSerializerModifier modifier;

public ModuleImpl(BeanSerializerModifier modifier)
public SerializerModifierModule(BeanSerializerModifier modifier)
{
super("test", Version.unknownVersion());
this.modifier = modifier;
Expand Down Expand Up @@ -178,6 +171,24 @@ public List<BeanPropertyWriter> changeProperties(SerializationConfig config,
}
}

// [Issue#539]: use post-modifier
static class EmptyBeanModifier539 extends BeanSerializerModifier
{
@Override
public List<BeanPropertyWriter> changeProperties(SerializationConfig config,
BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties)
{
System.err.println("DEBUG: changeProperties!");
return beanProperties;
}

@Override
public JsonSerializer<?> modifySerializer(SerializationConfig config,
BeanDescription beanDesc, JsonSerializer<?> serializer) {
System.err.println("DEBUG: modifySer!");
return new BogusBeanSerializer(42);
}
}
// [Issue#120], arrays, collections, maps

static class ArraySerializerModifier extends BeanSerializerModifier {
Expand Down Expand Up @@ -251,30 +262,30 @@ enum EnumABC { A, B, C };
public void testPropertyRemoval() throws Exception
{
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new ModuleImpl(new RemovingModifier("a")));
mapper.registerModule(new SerializerModifierModule(new RemovingModifier("a")));
Bean bean = new Bean();
assertEquals("{\"b\":\"b\"}", mapper.writeValueAsString(bean));
}

public void testPropertyReorder() throws Exception
{
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new ModuleImpl(new ReorderingModifier()));
mapper.registerModule(new SerializerModifierModule(new ReorderingModifier()));
Bean bean = new Bean();
assertEquals("{\"a\":\"a\",\"b\":\"b\"}", mapper.writeValueAsString(bean));
}

public void testBuilderReplacement() throws Exception
{
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new ModuleImpl(new BuilderModifier(new BogusBeanSerializer(17))));
mapper.registerModule(new SerializerModifierModule(new BuilderModifier(new BogusBeanSerializer(17))));
Bean bean = new Bean();
assertEquals("17", mapper.writeValueAsString(bean));
}
public void testSerializerReplacement() throws Exception
{
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new ModuleImpl(new ReplacingModifier(new BogusBeanSerializer(123))));
mapper.registerModule(new SerializerModifierModule(new ReplacingModifier(new BogusBeanSerializer(123))));
Bean bean = new Bean();
assertEquals("123", mapper.writeValueAsString(bean));
}
Expand All @@ -295,6 +306,22 @@ public void setupModule(SetupContext context)
assertEquals("{\"bogus\":\"foo\"}", json);
}

// [Issue#539]
public void testEmptyBean539() throws Exception
{
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new SimpleModule("test", Version.unknownVersion()) {
@Override
public void setupModule(SetupContext context)
{
super.setupModule(context);
context.addBeanSerializerModifier(new EmptyBeanModifier539());
}
});
String json = mapper.writeValueAsString(new EmptyBean());
assertEquals("42", json);
}

// [Issue#121]

public void testModifyArraySerializer() throws Exception
Expand Down

0 comments on commit 152aabb

Please sign in to comment.