Skip to content

Commit

Permalink
Fix #476
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Nov 18, 2016
1 parent 81c694b commit e1375b0
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 5 deletions.
1 change: 1 addition & 0 deletions release-notes/VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Project: jackson-databind

#219: SqlDateSerializer does not obey SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS
(reported by BrentDouglas@github)
#476: Allow "Serialize as POJO" using `@JsonFormat(shape=Shape.OBJECT)` class annotation
#507: Support for default `@JsonView` for a class
(suggested by Mark W)
#865: `JsonFormat.Shape.OBJECT` ignored when class implements `Map.Entry`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,7 @@ protected JsonSerializer<?> buildCollectionSerializer(SerializerProvider prov,
// We may also want to use serialize Collections "as beans", if (and only if)
// this is specified with `@JsonFormat(shape=Object)`
JsonFormat.Value format = beanDesc.findExpectedFormat(null);
if (format != null && format.getShape() == JsonFormat.Shape.OBJECT) {
if ((format != null) && format.getShape() == JsonFormat.Shape.OBJECT) {
return null;
}
Class<?> raw = type.getRawClass();
Expand Down Expand Up @@ -744,14 +744,21 @@ protected JsonSerializer<?> buildMapSerializer(SerializerProvider prov,
TypeSerializer elementTypeSerializer, JsonSerializer<Object> elementValueSerializer)
throws JsonMappingException
{
final SerializationConfig config = prov.getConfig();
// [databind#467]: This is where we could allow serialization "as POJO": But! It's
// nasty to undo, and does not apply on per-property basis. So, hardly optimal
JsonFormat.Value format = beanDesc.findExpectedFormat(null);
if ((format != null) && format.getShape() == JsonFormat.Shape.OBJECT) {
return null;
}

JsonSerializer<?> ser = null;

// Order of lookups:
// 1. Custom serializers
// 2. Annotations (@JsonValue, @JsonDeserialize)
// 3. Defaults

final SerializationConfig config = prov.getConfig();
for (Serializers serializers : customSerializers()) { // (1) Custom
ser = serializers.findMapSerializer(config, type, beanDesc,
keySerializer, elementTypeSerializer, elementValueSerializer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -430,9 +430,11 @@ public JsonSerializer<?> createContextual(SerializerProvider provider,
provider.getConfig(), desc, format);
return provider.handlePrimaryContextualization(ser, property);
}
// 16-Oct-2016, tatu: Ditto for `Map.Entry` subtypes
} else if (Map.Entry.class.isAssignableFrom(_handledType)) {
if (shape == JsonFormat.Shape.NATURAL) {
// 16-Oct-2016, tatu: Ditto for `Map`, `Map.Entry` subtypes
} else if (shape == JsonFormat.Shape.NATURAL) {
if (_beanType.isMapLikeType() && Map.class.isAssignableFrom(_handledType)) {
;
} else if (Map.Entry.class.isAssignableFrom(_handledType)) {
JavaType mapEntryType = _beanType.findSuperType(Map.Entry.class);

JavaType kt = mapEntryType.containedTypeOrUnknown(0);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package com.fasterxml.jackson.databind.format;

import java.util.LinkedHashMap;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.databind.*;

@SuppressWarnings("serial")
public class MapFormat476Test extends BaseMapTest
{
@JsonPropertyOrder({ "extra" })
static class Map476Base extends LinkedHashMap<String,Integer> {
public int extra = 13;
}

@JsonFormat(shape=JsonFormat.Shape.OBJECT)
static class Map476AsPOJO extends Map476Base { }

@JsonPropertyOrder({ "a", "b", "c" })
@JsonInclude(JsonInclude.Include.NON_NULL)
static class Bean476Container
{
public Map476AsPOJO a;
public Map476Base b;
@JsonFormat(shape=JsonFormat.Shape.OBJECT)
public Map476Base c;

public Bean476Container(int forA, int forB, int forC) {
if (forA != 0) {
a = new Map476AsPOJO();
a.put("value", forA);
}
if (forB != 0) {
b = new Map476Base();
b.put("value", forB);
}
if (forC != 0) {
c = new Map476Base();
c.put("value", forC);
}
}
}

static class Bean476Override
{
@JsonFormat(shape=JsonFormat.Shape.NATURAL)
public Map476AsPOJO stuff;

public Bean476Override(int value) {
stuff = new Map476AsPOJO();
stuff.put("value", value);
}
}

/*
/**********************************************************
/* Test methods
/**********************************************************
*/

final private ObjectMapper MAPPER = objectMapper();
// for [databind#476]: Maps as POJOs

public void testAsPOJOViaClass() throws Exception
{
String result = MAPPER.writeValueAsString(new Bean476Container(1,2,0));
assertEquals(aposToQuotes("{'a':{'extra':13,'empty':false},'b':{'value':2}}"),
result);
}

// Can't yet use per-property overrides at all
/*
public void testAsPOJOViaProperty() throws Exception
{
String result = MAPPER.writeValueAsString(new Bean476Container(1,0,3));
assertEquals(aposToQuotes("{'a':{'extra':13,'empty':false},'c':{'empty':false,'value':3}}"),
result);
}
public void testNaturalViaOverride() throws Exception
{
String result = MAPPER.writeValueAsString(new Bean476Override(123));
assertEquals(aposToQuotes("{'stuff':{'value':123}}"),
result);
}
*/
}

0 comments on commit e1375b0

Please sign in to comment.