Skip to content

Commit 57b287f

Browse files
committed
Start work on #688
1 parent a1dcf5e commit 57b287f

File tree

6 files changed

+164
-56
lines changed

6 files changed

+164
-56
lines changed

src/main/java/com/fasterxml/jackson/databind/DeserializationConfig.java

+9-16
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,17 @@
33
import java.text.DateFormat;
44
import java.util.*;
55

6-
import com.fasterxml.jackson.annotation.*;
6+
import com.fasterxml.jackson.annotation.JsonAutoDetect;
77
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
8+
import com.fasterxml.jackson.annotation.PropertyAccessor;
9+
810
import com.fasterxml.jackson.core.*;
9-
import com.fasterxml.jackson.databind.cfg.BaseSettings;
10-
import com.fasterxml.jackson.databind.cfg.ContextAttributes;
11-
import com.fasterxml.jackson.databind.cfg.HandlerInstantiator;
12-
import com.fasterxml.jackson.databind.cfg.MapperConfigBase;
11+
12+
import com.fasterxml.jackson.databind.cfg.*;
1313
import com.fasterxml.jackson.databind.deser.DeserializationProblemHandler;
14-
import com.fasterxml.jackson.databind.introspect.AnnotatedClass;
15-
import com.fasterxml.jackson.databind.introspect.ClassIntrospector;
16-
import com.fasterxml.jackson.databind.introspect.NopAnnotationIntrospector;
17-
import com.fasterxml.jackson.databind.introspect.VisibilityChecker;
18-
import com.fasterxml.jackson.databind.jsontype.NamedType;
19-
import com.fasterxml.jackson.databind.jsontype.SubtypeResolver;
20-
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
21-
import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder;
14+
import com.fasterxml.jackson.databind.introspect.*;
15+
import com.fasterxml.jackson.databind.jsontype.*;
2216
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
23-
import com.fasterxml.jackson.databind.type.ClassKey;
2417
import com.fasterxml.jackson.databind.type.TypeFactory;
2518
import com.fasterxml.jackson.databind.util.LinkedNode;
2619

@@ -80,7 +73,7 @@ public final class DeserializationConfig
8073
* Constructor used by ObjectMapper to create default configuration object instance.
8174
*/
8275
public DeserializationConfig(BaseSettings base,
83-
SubtypeResolver str, Map<ClassKey,Class<?>> mixins)
76+
SubtypeResolver str, SimpleMixInResolver mixins)
8477
{
8578
super(base, str, mixins);
8679
_deserFeatures = collectFeatureDefaults(DeserializationFeature.class);
@@ -170,7 +163,7 @@ private DeserializationConfig(DeserializationConfig src, Class<?> view)
170163
/**
171164
* @since 2.1
172165
*/
173-
protected DeserializationConfig(DeserializationConfig src, Map<ClassKey,Class<?>> mixins)
166+
protected DeserializationConfig(DeserializationConfig src, SimpleMixInResolver mixins)
174167
{
175168
super(src, mixins);
176169
_deserFeatures = src._deserFeatures;

src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java

+13-14
Original file line numberDiff line numberDiff line change
@@ -272,8 +272,8 @@ public boolean useForType(JavaType t)
272272
* you can think of it as injecting annotations between the target
273273
* class and its sub-classes (or interfaces)
274274
*/
275-
protected final HashMap<ClassKey,Class<?>> _mixInAnnotations;
276-
275+
protected SimpleMixInResolver _mixInAnnotations;
276+
277277
/*
278278
/**********************************************************
279279
/* Configuration settings, serialization
@@ -414,7 +414,7 @@ protected ObjectMapper(ObjectMapper src)
414414
_typeFactory = src._typeFactory;
415415
_injectableValues = src._injectableValues;
416416

417-
HashMap<ClassKey,Class<?>> mixins = new HashMap<ClassKey,Class<?>>(src._mixInAnnotations);
417+
SimpleMixInResolver mixins = src._mixInAnnotations.copy();
418418
_mixInAnnotations = mixins;
419419
_serializationConfig = new SerializationConfig(src._serializationConfig, mixins);
420420
_deserializationConfig = new DeserializationConfig(src._deserializationConfig, mixins);
@@ -459,7 +459,7 @@ public ObjectMapper(JsonFactory jf,
459459
// and default type factory is shared one
460460
_typeFactory = TypeFactory.defaultInstance();
461461

462-
HashMap<ClassKey,Class<?>> mixins = new HashMap<ClassKey,Class<?>>();
462+
SimpleMixInResolver mixins = new SimpleMixInResolver(null);
463463
_mixInAnnotations = mixins;
464464

465465
BaseSettings base = DEFAULT_BASE.withClassIntrospector(defaultClassIntrospector());
@@ -988,17 +988,16 @@ public SerializerProvider getSerializerProvider() {
988988
* Annotations from source classes (and their supertypes)
989989
* will <b>override</b>
990990
* annotations that target classes (and their super-types) have.
991+
*<p>
992+
* Note that this method will CLEAR any previously defined mix-ins
993+
* for this mapper.
991994
*
992995
* @since 2.5
993996
*/
994997
public ObjectMapper setMixIns(Map<Class<?>, Class<?>> sourceMixins)
995998
{
996-
_mixInAnnotations.clear();
997-
if (sourceMixins != null && sourceMixins.size() > 0) {
998-
for (Map.Entry<Class<?>,Class<?>> en : sourceMixins.entrySet()) {
999-
_mixInAnnotations.put(new ClassKey(en.getKey()), en.getValue());
1000-
}
1001-
}
999+
// NOTE: does NOT change possible externally configured resolver, just local defs
1000+
_mixInAnnotations.setLocalDefinitions(sourceMixins);
10021001
return this;
10031002
}
10041003

@@ -1016,19 +1015,19 @@ public ObjectMapper setMixIns(Map<Class<?>, Class<?>> sourceMixins)
10161015
*/
10171016
public ObjectMapper addMixIn(Class<?> target, Class<?> mixinSource)
10181017
{
1019-
_mixInAnnotations.put(new ClassKey(target), mixinSource);
1018+
_mixInAnnotations.addLocalDefinition(target, mixinSource);
10201019
return this;
10211020
}
10221021

10231022
public Class<?> findMixInClassFor(Class<?> cls) {
1024-
return (_mixInAnnotations == null) ? null : _mixInAnnotations.get(new ClassKey(cls));
1023+
return _mixInAnnotations.findMixInClassFor(cls);
10251024
}
10261025

1026+
// For testing only:
10271027
public int mixInCount() {
1028-
return (_mixInAnnotations == null) ? 0 : _mixInAnnotations.size();
1028+
return _mixInAnnotations.localSize();
10291029
}
10301030

1031-
10321031
/**
10331032
* @deprecated Since 2.5: replaced by a fluent form of the method; {@link #setMixIns}.
10341033
*/

src/main/java/com/fasterxml/jackson/databind/SerializationConfig.java

+9-8
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,21 @@
33
import java.text.DateFormat;
44
import java.util.*;
55

6-
import com.fasterxml.jackson.annotation.*;
6+
import com.fasterxml.jackson.annotation.JsonAutoDetect;
77
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
8+
import com.fasterxml.jackson.annotation.JsonInclude;
9+
import com.fasterxml.jackson.annotation.PropertyAccessor;
10+
811
import com.fasterxml.jackson.core.*;
9-
import com.fasterxml.jackson.databind.cfg.BaseSettings;
10-
import com.fasterxml.jackson.databind.cfg.ContextAttributes;
11-
import com.fasterxml.jackson.databind.cfg.HandlerInstantiator;
12-
import com.fasterxml.jackson.databind.cfg.MapperConfigBase;
12+
13+
import com.fasterxml.jackson.databind.cfg.*;
1314
import com.fasterxml.jackson.databind.introspect.ClassIntrospector;
15+
import com.fasterxml.jackson.databind.introspect.SimpleMixInResolver;
1416
import com.fasterxml.jackson.databind.introspect.VisibilityChecker;
1517
import com.fasterxml.jackson.databind.jsontype.SubtypeResolver;
1618
import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder;
1719
import com.fasterxml.jackson.databind.ser.FilterProvider;
1820
import com.fasterxml.jackson.databind.ser.SerializerFactory;
19-
import com.fasterxml.jackson.databind.type.ClassKey;
2021
import com.fasterxml.jackson.databind.type.TypeFactory;
2122

2223
/**
@@ -79,7 +80,7 @@ public final class SerializationConfig
7980
* Constructor used by ObjectMapper to create default configuration object instance.
8081
*/
8182
public SerializationConfig(BaseSettings base,
82-
SubtypeResolver str, Map<ClassKey,Class<?>> mixins)
83+
SubtypeResolver str, SimpleMixInResolver mixins)
8384
{
8485
super(base, str, mixins);
8586
_serFeatures = collectFeatureDefaults(SerializationFeature.class);
@@ -163,7 +164,7 @@ private SerializationConfig(SerializationConfig src, String rootName)
163164
/**
164165
* @since 2.1
165166
*/
166-
protected SerializationConfig(SerializationConfig src, Map<ClassKey,Class<?>> mixins)
167+
protected SerializationConfig(SerializationConfig src, SimpleMixInResolver mixins)
167168
{
168169
super(src, mixins);
169170
_serFeatures = src._serFeatures;

src/main/java/com/fasterxml/jackson/databind/cfg/MapperConfigBase.java

+30-18
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,19 @@
1212
import com.fasterxml.jackson.databind.MapperFeature;
1313
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
1414
import com.fasterxml.jackson.databind.introspect.ClassIntrospector;
15+
import com.fasterxml.jackson.databind.introspect.ClassIntrospector.MixInResolver;
16+
import com.fasterxml.jackson.databind.introspect.SimpleMixInResolver;
1517
import com.fasterxml.jackson.databind.introspect.VisibilityChecker;
1618
import com.fasterxml.jackson.databind.jsontype.SubtypeResolver;
1719
import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder;
18-
import com.fasterxml.jackson.databind.type.ClassKey;
1920
import com.fasterxml.jackson.databind.type.TypeFactory;
2021

22+
@SuppressWarnings("serial")
2123
public abstract class MapperConfigBase<CFG extends ConfigFeature,
2224
T extends MapperConfigBase<CFG,T>>
2325
extends MapperConfig<T>
2426
implements java.io.Serializable
2527
{
26-
private static final long serialVersionUID = 6062961959359172474L;
27-
2828
private final static int DEFAULT_MAPPER_FEATURES = collectFeatureDefaults(MapperFeature.class);
2929

3030
/*
@@ -36,8 +36,10 @@ public abstract class MapperConfigBase<CFG extends ConfigFeature,
3636
/**
3737
* Mix-in annotation mappings to use, if any: immutable,
3838
* can not be changed once defined.
39+
*
40+
* @since 2.6
3941
*/
40-
protected final Map<ClassKey,Class<?>> _mixInAnnotations;
42+
protected final SimpleMixInResolver _mixIns;
4143

4244
/**
4345
* Registered concrete subtypes that can be used instead of (or
@@ -79,10 +81,10 @@ public abstract class MapperConfigBase<CFG extends ConfigFeature,
7981
* that of creating fluent copies)
8082
*/
8183
protected MapperConfigBase(BaseSettings base,
82-
SubtypeResolver str, Map<ClassKey,Class<?>> mixins)
84+
SubtypeResolver str, SimpleMixInResolver mixins)
8385
{
8486
super(base, DEFAULT_MAPPER_FEATURES);
85-
_mixInAnnotations = mixins;
87+
_mixIns = mixins;
8688
_subtypeResolver = str;
8789
_rootName = null;
8890
_view = null;
@@ -97,7 +99,7 @@ protected MapperConfigBase(BaseSettings base,
9799
protected MapperConfigBase(MapperConfigBase<CFG,T> src)
98100
{
99101
super(src);
100-
_mixInAnnotations = src._mixInAnnotations;
102+
_mixIns = src._mixIns;
101103
_subtypeResolver = src._subtypeResolver;
102104
_rootName = src._rootName;
103105
_view = src._view;
@@ -107,7 +109,7 @@ protected MapperConfigBase(MapperConfigBase<CFG,T> src)
107109
protected MapperConfigBase(MapperConfigBase<CFG,T> src, BaseSettings base)
108110
{
109111
super(base, src._mapperFeatures);
110-
_mixInAnnotations = src._mixInAnnotations;
112+
_mixIns = src._mixIns;
111113
_subtypeResolver = src._subtypeResolver;
112114
_rootName = src._rootName;
113115
_view = src._view;
@@ -117,7 +119,7 @@ protected MapperConfigBase(MapperConfigBase<CFG,T> src, BaseSettings base)
117119
protected MapperConfigBase(MapperConfigBase<CFG,T> src, int mapperFeatures)
118120
{
119121
super(src._base, mapperFeatures);
120-
_mixInAnnotations = src._mixInAnnotations;
122+
_mixIns = src._mixIns;
121123
_subtypeResolver = src._subtypeResolver;
122124
_rootName = src._rootName;
123125
_view = src._view;
@@ -126,7 +128,7 @@ protected MapperConfigBase(MapperConfigBase<CFG,T> src, int mapperFeatures)
126128

127129
protected MapperConfigBase(MapperConfigBase<CFG,T> src, SubtypeResolver str) {
128130
super(src);
129-
_mixInAnnotations = src._mixInAnnotations;
131+
_mixIns = src._mixIns;
130132
_subtypeResolver = str;
131133
_rootName = src._rootName;
132134
_view = src._view;
@@ -135,7 +137,7 @@ protected MapperConfigBase(MapperConfigBase<CFG,T> src, SubtypeResolver str) {
135137

136138
protected MapperConfigBase(MapperConfigBase<CFG,T> src, String rootName) {
137139
super(src);
138-
_mixInAnnotations = src._mixInAnnotations;
140+
_mixIns = src._mixIns;
139141
_subtypeResolver = src._subtypeResolver;
140142
_rootName = rootName;
141143
_view = src._view;
@@ -145,7 +147,7 @@ protected MapperConfigBase(MapperConfigBase<CFG,T> src, String rootName) {
145147
protected MapperConfigBase(MapperConfigBase<CFG,T> src, Class<?> view)
146148
{
147149
super(src);
148-
_mixInAnnotations = src._mixInAnnotations;
150+
_mixIns = src._mixIns;
149151
_subtypeResolver = src._subtypeResolver;
150152
_rootName = src._rootName;
151153
_view = view;
@@ -155,10 +157,10 @@ protected MapperConfigBase(MapperConfigBase<CFG,T> src, Class<?> view)
155157
/**
156158
* @since 2.1
157159
*/
158-
protected MapperConfigBase(MapperConfigBase<CFG,T> src, Map<ClassKey,Class<?>> mixins)
160+
protected MapperConfigBase(MapperConfigBase<CFG,T> src, SimpleMixInResolver mixins)
159161
{
160162
super(src);
161-
_mixInAnnotations = mixins;
163+
_mixIns = mixins;
162164
_subtypeResolver = src._subtypeResolver;
163165
_rootName = src._rootName;
164166
_view = src._view;
@@ -171,7 +173,7 @@ protected MapperConfigBase(MapperConfigBase<CFG,T> src, Map<ClassKey,Class<?>> m
171173
protected MapperConfigBase(MapperConfigBase<CFG,T> src, ContextAttributes attr)
172174
{
173175
super(src);
174-
_mixInAnnotations = src._mixInAnnotations;
176+
_mixIns = src._mixIns;
175177
_subtypeResolver = src._subtypeResolver;
176178
_rootName = src._rootName;
177179
_view = src._view;
@@ -401,10 +403,20 @@ public final ContextAttributes getAttributes() {
401403
*/
402404
@Override
403405
public final Class<?> findMixInClassFor(Class<?> cls) {
404-
return (_mixInAnnotations == null) ? null : _mixInAnnotations.get(new ClassKey(cls));
406+
return _mixIns.findMixInClassFor(cls);
405407
}
406408

409+
// Not really relevant here (should not get called)
410+
@Override
411+
public MixInResolver copy() {
412+
throw new UnsupportedOperationException();
413+
}
414+
415+
/**
416+
* Test-only method -- does not reflect possibly open-ended set that external
417+
* mix-in resolver might provide.
418+
*/
407419
public final int mixInCount() {
408-
return (_mixInAnnotations == null) ? 0 : _mixInAnnotations.size();
420+
return _mixIns.localSize();
409421
}
410-
}
422+
}

src/main/java/com/fasterxml/jackson/databind/introspect/ClassIntrospector.java

+10
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,16 @@ public interface MixInResolver
3333
* annotations) for given class
3434
*/
3535
public Class<?> findMixInClassFor(Class<?> cls);
36+
37+
/**
38+
* Method called to create a new, non-shared copy, to be used by different
39+
* <code>ObjectMapper</code> instance, and one that should not be connected
40+
* to this instance, if resolver has mutable state.
41+
* If resolver is immutable may simply return `this`.
42+
*
43+
* @since 2.6
44+
*/
45+
public MixInResolver copy();
3646
}
3747

3848
protected ClassIntrospector() { }

0 commit comments

Comments
 (0)