Skip to content

Commit

Permalink
Fix #299
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Dec 29, 2014
1 parent 57a51dc commit dfa1b44
Show file tree
Hide file tree
Showing 16 changed files with 65 additions and 30 deletions.
2 changes: 2 additions & 0 deletions release-notes/VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ Project: jackson-databind
#113: Problem deserializing polymorphic types with @JsonCreator
#165: Add `DeserializationContext.getContextualType()` to let deserializer
known the expected type.
#299: Add `DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS` to allow missing
Object Ids (as global default)
#408: External type id does not allow use of 'visible=true'
#421: @JsonCreator not used in case of multiple creators with parameter names
(reported by Lovro P, lpandzic@github)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,22 @@ public enum DeserializationFeature implements ConfigFeature
*/
FAIL_ON_IGNORED_PROPERTIES(false),

/**
* Feature that determines what happens if an Object Id reference is encountered
* that does not refer to an actual Object with that id ("unresolved Object Id"):
* either an exception is thrown (<code>true</code>), or a null object is used
* instead (<code>false</code>).
* Note that if this is set to <code>false</code>, no further processing is done;
* specifically, if reference is defined via setter method, that method will NOT
* be called.
*<p>
* Feature is enabled by default, so that unknown Object Ids will result in an
* exception being thrown, at the end of deserialization.
*
* @since 2.5
*/
FAIL_ON_UNRESOLVED_OBJECT_IDS(true),

/**
* Feature that determines whether Jackson code should catch
* and wrap {@link Exception}s (but never {@link Error}s!)
Expand All @@ -188,7 +204,7 @@ public enum DeserializationFeature implements ConfigFeature
* Feature is enabled by default.
*/
WRAP_EXCEPTIONS(true),

/*
/******************************************************
/* Structural conversion features
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,15 +138,18 @@ public void checkUnresolvedObjectId() throws UnresolvedForwardReference
if (_objectIds == null) {
return;
}

// 29-Dec-2014, tatu: As per [databind#299], may also just let unresolved refs be...
if (!isEnabled(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS)) {
return;
}
UnresolvedForwardReference exception = null;
for (Entry<IdKey,ReadableObjectId> entry : _objectIds.entrySet()) {
ReadableObjectId roid = entry.getValue();
if (roid.hasReferringProperties()) {
if (exception == null) {
exception = new UnresolvedForwardReference("Unresolved forward references for: ");
}
for (Iterator<Referring> iterator = roid.referringProperties(); iterator.hasNext();) {
for (Iterator<Referring> iterator = roid.referringProperties(); iterator.hasNext(); ) {
Referring referring = iterator.next();
exception.addUnresolvedId(roid.getKey().key, referring.getBeanType(), referring.getLocation());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,18 +84,25 @@ public ContainerSerializer<?> withValueTypeSerializer(TypeSerializer vts) {
* {@link com.fasterxml.jackson.databind.SerializerProvider#findValueSerializer}.
*/
public abstract JsonSerializer<?> getContentSerializer();

/*
/**********************************************************
/* Abstract methods for sub-classes to implement
/**********************************************************
*/

/* Overridden as abstract, to force re-implementation; necessary for all
* collection types.
*/
@Override
public abstract boolean isEmpty(T value);
@Deprecated
public boolean isEmpty(T value) {
return isEmpty(null, value);
}

// since 2.5: should be declared abstract in future (2.6)
// @Override
// public abstract boolean isEmpty(SerializerProvider prov, T value);

/**
* Method called to determine if the given value (of type handled by
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public IndexedListSerializer withResolved(BeanProperty property,
*/

@Override
public boolean isEmpty(List<?> value) {
public boolean isEmpty(SerializerProvider prov, List<?> value) {
return (value == null) || value.isEmpty();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public IteratorSerializer(IteratorSerializer src,
}

@Override
public boolean isEmpty(Iterator<?> value) {
public boolean isEmpty(SerializerProvider prov, Iterator<?> value) {
return (value == null) || !value.hasNext();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ public boolean hasSingleElement(Map.Entry<?,?> value) {
}

@Override
public boolean isEmpty(Entry<?, ?> value) {
public boolean isEmpty(SerializerProvider prov, Entry<?, ?> value) {
return (value == null);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ public JsonSerializer<?> getContentSerializer() {
}

@Override
public boolean isEmpty(String[] value) {
public boolean isEmpty(SerializerProvider prov, String[] value) {
return (value == null) || (value.length == 0);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public CollectionSerializer withResolved(BeanProperty property,
*/

@Override
public boolean isEmpty(Collection<?> value) {
public boolean isEmpty(SerializerProvider prov, Collection<?> value) {
return (value == null) || value.isEmpty();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ public JsonSerializer<?> getContentSerializer() {
}

@Override
public boolean isEmpty(EnumMap<? extends Enum<?>,?> value) {
public boolean isEmpty(SerializerProvider prov, EnumMap<? extends Enum<?>,?> value) {
return (value == null) || value.isEmpty();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public EnumSetSerializer withResolved(BeanProperty property,
}

@Override
public boolean isEmpty(EnumSet<? extends Enum<?>> value) {
public boolean isEmpty(SerializerProvider prov, EnumSet<? extends Enum<?>> value) {
return (value == null) || value.isEmpty();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public IterableSerializer withResolved(BeanProperty property,
}

@Override
public boolean isEmpty(Iterable<?> value) {
public boolean isEmpty(SerializerProvider prov, Iterable<?> value) {
// Not really good way to implement this, but has to do for now:
return (value == null) || !value.iterator().hasNext();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ public JsonSerializer<?> getContentSerializer() {
}

@Override
public boolean isEmpty(Map<?,?> value) {
public boolean isEmpty(SerializerProvider prov, Map<?,?> value) {
return (value == null) || value.isEmpty();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ public JsonSerializer<?> getContentSerializer() {
}

@Override
public boolean isEmpty(Object[] value) {
public boolean isEmpty(SerializerProvider prov, Object[] value) {
return (value == null) || (value.length == 0);
}

Expand All @@ -190,8 +190,7 @@ public boolean hasSingleElement(Object[] value) {
*/

@Override
public final void serialize(Object[] value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonGenerationException
public final void serialize(Object[] value, JsonGenerator jgen, SerializerProvider provider) throws IOException
{
final int len = value.length;
if ((len == 1) && provider.isEnabled(SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED)) {
Expand All @@ -204,8 +203,7 @@ public final void serialize(Object[] value, JsonGenerator jgen, SerializerProvid
}

@Override
public void serializeContents(Object[] value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonGenerationException
public void serializeContents(Object[] value, JsonGenerator jgen, SerializerProvider provider) throws IOException
{
final int len = value.length;
if (len == 0) {
Expand Down Expand Up @@ -262,8 +260,7 @@ public void serializeContents(Object[] value, JsonGenerator jgen, SerializerProv
}

public void serializeContentsUsing(Object[] value, JsonGenerator jgen, SerializerProvider provider,
JsonSerializer<Object> ser)
throws IOException, JsonGenerationException
JsonSerializer<Object> ser) throws IOException
{
final int len = value.length;
final TypeSerializer typeSer = _valueTypeSerializer;
Expand Down Expand Up @@ -297,8 +294,7 @@ public void serializeContentsUsing(Object[] value, JsonGenerator jgen, Serialize
}
}

public void serializeTypedContents(Object[] value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonGenerationException
public void serializeTypedContents(Object[] value, JsonGenerator jgen, SerializerProvider provider) throws IOException
{
final int len = value.length;
final TypeSerializer typeSer = _valueTypeSerializer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public JsonSerializer<?> getContentSerializer() {
}

@Override
public boolean isEmpty(boolean[] value) {
public boolean isEmpty(SerializerProvider prov, boolean[] value) {
return (value == null) || (value.length == 0);
}

Expand Down Expand Up @@ -249,7 +249,7 @@ public JsonSerializer<?> getContentSerializer() {
}

@Override
public boolean isEmpty(short[] value) {
public boolean isEmpty(SerializerProvider prov, short[] value) {
return (value == null) || (value.length == 0);
}

Expand Down Expand Up @@ -417,7 +417,7 @@ public JsonSerializer<?> getContentSerializer() {
}

@Override
public boolean isEmpty(int[] value) {
public boolean isEmpty(SerializerProvider prov, int[] value) {
return (value == null) || (value.length == 0);
}

Expand Down Expand Up @@ -494,7 +494,7 @@ public JsonSerializer<?> getContentSerializer() {
}

@Override
public boolean isEmpty(long[] value) {
public boolean isEmpty(SerializerProvider prov, long[] value) {
return (value == null) || (value.length == 0);
}

Expand Down Expand Up @@ -585,7 +585,7 @@ public JsonSerializer<?> getContentSerializer() {
}

@Override
public boolean isEmpty(float[] value) {
public boolean isEmpty(SerializerProvider prov, float[] value) {
return (value == null) || (value.length == 0);
}

Expand Down Expand Up @@ -670,7 +670,7 @@ public JsonSerializer<?> getContentSerializer() {
}

@Override
public boolean isEmpty(double[] value) {
public boolean isEmpty(SerializerProvider prov, double[] value) {
return (value == null) || (value.length == 0);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import com.fasterxml.jackson.annotation.ObjectIdResolver;
import com.fasterxml.jackson.databind.BaseMapTest;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.cfg.ContextAttributes;
import com.fasterxml.jackson.databind.deser.UnresolvedForwardReference;
Expand Down Expand Up @@ -341,6 +342,16 @@ public void testUnresolvedForwardReference()
}
}

// [databind#299]: Allow unresolved ids to become nulls
public void testUnresolvableAsNull() throws Exception
{
IdWrapper w = mapper.reader(IdWrapper.class)
.without(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS)
.readValue(aposToQuotes("{'node':123}"));
assertNotNull(w);
assertNull(w.node);
}

public void testKeepCollectionOrdering() throws Exception
{
String json = "{\"employees\":[2,1,"
Expand Down

0 comments on commit dfa1b44

Please sign in to comment.