Skip to content

Commit

Permalink
Fix #245
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Oct 29, 2014
1 parent 98f2090 commit 23328aa
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 13 deletions.
3 changes: 3 additions & 0 deletions release-notes/VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ Project: jackson-databind

(jackson-core)#158: Setter confusion on assignable types
(reported by tsquared2763@github)
#245: Calls to ObjectMapper.addMixInAnnotations() on an instance returned by ObjectMapper.copy()
don't work
(reported by Erik D)
#580: delegate deserializers choke on a (single) abstract/polymorphic parameter
(reported by Ian B, tea-dragon@github)
#590: Binding invalid Currency gives nonsense at end of the message
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,19 @@ protected DeserializationContext(DeserializationContext src,
_attributes = config.getAttributes();
}

/**
* Copy-constructor for use with <code>copy()</code> by {@link ObjectMapper#copy()}
*/
protected DeserializationContext(DeserializationContext src) {
_cache = new DeserializerCache();
_factory = src._factory;

_config = src._config;
_featureFlags = src._featureFlags;
_view = src._view;
_injectableValues = null;
}

/*
/**********************************************************
/* DatabindContext implementation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -401,13 +401,12 @@ protected ObjectMapper(ObjectMapper src)
_subtypeResolver = src._subtypeResolver;
_rootNames = new RootNameLookup();
_typeFactory = src._typeFactory;
_serializationConfig = src._serializationConfig;
HashMap<ClassKey,Class<?>> mixins = new HashMap<ClassKey,Class<?>>(src._mixInAnnotations);
_mixInAnnotations = mixins;
_serializationConfig = new SerializationConfig(src._serializationConfig, mixins);
_deserializationConfig = new DeserializationConfig(src._deserializationConfig, mixins);
_serializerProvider = src._serializerProvider;
_deserializationContext = src._deserializationContext;
_serializerProvider = src._serializerProvider.copy();
_deserializationContext = src._deserializationContext.copy();

// Default serializer factory is stateless, can just assign
_serializerFactory = src._serializerFactory;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ public abstract class SerializerProvider

/**
* View used for currently active serialization, if any.
* Only set for non-blueprint instances.
*/
final protected Class<?> _serializationView;

Expand All @@ -79,6 +80,7 @@ public abstract class SerializerProvider

/**
* Factory used for constructing actual serializer instances.
* Only set for non-blueprint instances.
*/
final protected SerializerFactory _serializerFactory;

Expand All @@ -100,6 +102,7 @@ public abstract class SerializerProvider

/**
* Lazily-constructed holder for per-call attributes.
* Only set for non-blueprint instances.
*
* @since 2.3
*/
Expand Down Expand Up @@ -212,10 +215,12 @@ protected SerializerProvider(SerializerProvider src,
_unknownTypeSerializer = src._unknownTypeSerializer;
_keySerializer = src._keySerializer;
_nullValueSerializer = src._nullValueSerializer;
_stdNullValueSerializer = (_nullValueSerializer == DEFAULT_NULL_KEY_SERIALIZER);
_nullKeySerializer = src._nullKeySerializer;
_rootNames = src._rootNames;

_stdNullValueSerializer = (_nullValueSerializer == DEFAULT_NULL_KEY_SERIALIZER);

_rootNames = src._rootNames;

/* Non-blueprint instances do have a read-only map; one that doesn't
* need synchronization for lookups.
*/
Expand All @@ -224,6 +229,32 @@ protected SerializerProvider(SerializerProvider src,
_serializationView = config.getActiveView();
_attributes = config.getAttributes();
}

/**
* Copy-constructor used when making a {@link #copy} of a blueprint
* object.
*
* @since 2.4.4
*/
protected SerializerProvider(SerializerProvider src)
{
// since this is assumed to be a blue-print instance, many settings missing:
_config = null;
_serializationView = null;
_serializerFactory = null;
_knownSerializers = null;

// and others initialized to default empty state
_serializerCache = new SerializerCache();
_rootNames = new RootNameLookup();

_unknownTypeSerializer = src._unknownTypeSerializer;
_keySerializer = src._keySerializer;
_nullValueSerializer = src._nullValueSerializer;
_nullKeySerializer = src._nullKeySerializer;

_stdNullValueSerializer = src._stdNullValueSerializer;
}

/*
/**********************************************************
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package com.fasterxml.jackson.databind.deser;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.*;
import java.util.Map.Entry;

import com.fasterxml.jackson.annotation.ObjectIdGenerator;
Expand Down Expand Up @@ -56,6 +53,25 @@ protected DefaultDeserializationContext(DefaultDeserializationContext src,
super(src, factory);
}

/**
* @since 2.4.4
*/
protected DefaultDeserializationContext(DefaultDeserializationContext src) {
super(src);
}

/**
* Method needed to ensure that {@link ObjectMapper#copy} will work
* properly; specifically, that caches are cleared, but settings
* will otherwise remain identical; and that no sharing of state
* occurs.
*
* @since 2.4.4
*/
public DefaultDeserializationContext copy() {
throw new IllegalStateException("DefaultDeserializationContext sub-class not overriding copy()");
}

/*
/**********************************************************
/* Abstract methods impls, Object Id
Expand Down Expand Up @@ -270,9 +286,19 @@ protected Impl(Impl src,
super(src, config, jp, values);
}

protected Impl(Impl src) { super(src); }

protected Impl(Impl src, DeserializerFactory factory) {
super(src, factory);
}

@Override
public DefaultDeserializationContext copy() {
if (getClass() != Impl.class) {
return super.copy();
}
return new Impl(this);
}

@Override
public DefaultDeserializationContext createInstance(DeserializationConfig config,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
import java.util.concurrent.atomic.AtomicReference;

import com.fasterxml.jackson.annotation.ObjectIdGenerator;

import com.fasterxml.jackson.core.JsonGenerator;

import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.cfg.HandlerInstantiator;
import com.fasterxml.jackson.databind.introspect.Annotated;
Expand Down Expand Up @@ -62,6 +60,22 @@ protected DefaultSerializerProvider(SerializerProvider src,
super(src, config, f);
}

protected DefaultSerializerProvider(DefaultSerializerProvider src) {
super(src);
}

/**
* Method needed to ensure that {@link ObjectMapper#copy} will work
* properly; specifically, that caches are cleared, but settings
* will otherwise remain identical; and that no sharing of state
* occurs.
*
* @since 2.4.4
*/
public DefaultSerializerProvider copy() {
throw new IllegalStateException("DefaultSerializerProvider sub-class not overriding copy()");
}

/*
/**********************************************************
/* Extended API: methods that ObjectMapper will call
Expand Down Expand Up @@ -492,11 +506,21 @@ public final static class Impl extends DefaultSerializerProvider {
private static final long serialVersionUID = 1L;

public Impl() { super(); }
public Impl(Impl src) { super(src); }

protected Impl(SerializerProvider src, SerializationConfig config,SerializerFactory f) {
super(src, config, f);
}

@Override
public DefaultSerializerProvider copy()
{
if (getClass() != Impl.class) {
return super.copy();
}
return new Impl(this);
}

@Override
public Impl createInstance(SerializationConfig config, SerializerFactory jsf) {
return new Impl(this, config, jsf);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,13 @@ public void testClassMixInsMidLevel() throws IOException
assertEquals(1, result.size());
assertEquals("c2", result.get("c"));

// and related to [databind#245], retry with a copy
ObjectMapper mapper2 = mapper.copy();
// and related to [databind#245], apply mix-ins to a copy of ObjectMapper
ObjectMapper mapper2 = new ObjectMapper();
result = writeAndMap(mapper2, bean);
assertEquals(2, result.size());
ObjectMapper mapper3 = mapper2.copy();
mapper3.addMixInAnnotations(BaseClass.class, MixInAutoDetect.class);
result = writeAndMap(mapper3, bean);
assertEquals(1, result.size());
assertEquals("c2", result.get("c"));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ static class MyNullProvider extends DefaultSerializerProvider
public MyNullProvider(MyNullProvider base, SerializationConfig config, SerializerFactory jsf) {
super(base, config, jsf);
}

// not really a proper impl, but has to do
@Override
public DefaultSerializerProvider copy() {
return this;
}

@Override
public DefaultSerializerProvider createInstance(SerializationConfig config, SerializerFactory jsf) {
Expand Down

0 comments on commit 23328aa

Please sign in to comment.