Skip to content

Commit

Permalink
Start work on #688
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Apr 3, 2015
1 parent a1dcf5e commit 57b287f
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,17 @@
import java.text.DateFormat;
import java.util.*;

import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.PropertyAccessor;

import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.cfg.BaseSettings;
import com.fasterxml.jackson.databind.cfg.ContextAttributes;
import com.fasterxml.jackson.databind.cfg.HandlerInstantiator;
import com.fasterxml.jackson.databind.cfg.MapperConfigBase;

import com.fasterxml.jackson.databind.cfg.*;
import com.fasterxml.jackson.databind.deser.DeserializationProblemHandler;
import com.fasterxml.jackson.databind.introspect.AnnotatedClass;
import com.fasterxml.jackson.databind.introspect.ClassIntrospector;
import com.fasterxml.jackson.databind.introspect.NopAnnotationIntrospector;
import com.fasterxml.jackson.databind.introspect.VisibilityChecker;
import com.fasterxml.jackson.databind.jsontype.NamedType;
import com.fasterxml.jackson.databind.jsontype.SubtypeResolver;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder;
import com.fasterxml.jackson.databind.introspect.*;
import com.fasterxml.jackson.databind.jsontype.*;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.type.ClassKey;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.databind.util.LinkedNode;

Expand Down Expand Up @@ -80,7 +73,7 @@ public final class DeserializationConfig
* Constructor used by ObjectMapper to create default configuration object instance.
*/
public DeserializationConfig(BaseSettings base,
SubtypeResolver str, Map<ClassKey,Class<?>> mixins)
SubtypeResolver str, SimpleMixInResolver mixins)
{
super(base, str, mixins);
_deserFeatures = collectFeatureDefaults(DeserializationFeature.class);
Expand Down Expand Up @@ -170,7 +163,7 @@ private DeserializationConfig(DeserializationConfig src, Class<?> view)
/**
* @since 2.1
*/
protected DeserializationConfig(DeserializationConfig src, Map<ClassKey,Class<?>> mixins)
protected DeserializationConfig(DeserializationConfig src, SimpleMixInResolver mixins)
{
super(src, mixins);
_deserFeatures = src._deserFeatures;
Expand Down
27 changes: 13 additions & 14 deletions src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -272,8 +272,8 @@ public boolean useForType(JavaType t)
* you can think of it as injecting annotations between the target
* class and its sub-classes (or interfaces)
*/
protected final HashMap<ClassKey,Class<?>> _mixInAnnotations;
protected SimpleMixInResolver _mixInAnnotations;

/*
/**********************************************************
/* Configuration settings, serialization
Expand Down Expand Up @@ -414,7 +414,7 @@ protected ObjectMapper(ObjectMapper src)
_typeFactory = src._typeFactory;
_injectableValues = src._injectableValues;

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

HashMap<ClassKey,Class<?>> mixins = new HashMap<ClassKey,Class<?>>();
SimpleMixInResolver mixins = new SimpleMixInResolver(null);
_mixInAnnotations = mixins;

BaseSettings base = DEFAULT_BASE.withClassIntrospector(defaultClassIntrospector());
Expand Down Expand Up @@ -988,17 +988,16 @@ public SerializerProvider getSerializerProvider() {
* Annotations from source classes (and their supertypes)
* will <b>override</b>
* annotations that target classes (and their super-types) have.
*<p>
* Note that this method will CLEAR any previously defined mix-ins
* for this mapper.
*
* @since 2.5
*/
public ObjectMapper setMixIns(Map<Class<?>, Class<?>> sourceMixins)
{
_mixInAnnotations.clear();
if (sourceMixins != null && sourceMixins.size() > 0) {
for (Map.Entry<Class<?>,Class<?>> en : sourceMixins.entrySet()) {
_mixInAnnotations.put(new ClassKey(en.getKey()), en.getValue());
}
}
// NOTE: does NOT change possible externally configured resolver, just local defs
_mixInAnnotations.setLocalDefinitions(sourceMixins);
return this;
}

Expand All @@ -1016,19 +1015,19 @@ public ObjectMapper setMixIns(Map<Class<?>, Class<?>> sourceMixins)
*/
public ObjectMapper addMixIn(Class<?> target, Class<?> mixinSource)
{
_mixInAnnotations.put(new ClassKey(target), mixinSource);
_mixInAnnotations.addLocalDefinition(target, mixinSource);
return this;
}

public Class<?> findMixInClassFor(Class<?> cls) {
return (_mixInAnnotations == null) ? null : _mixInAnnotations.get(new ClassKey(cls));
return _mixInAnnotations.findMixInClassFor(cls);
}

// For testing only:
public int mixInCount() {
return (_mixInAnnotations == null) ? 0 : _mixInAnnotations.size();
return _mixInAnnotations.localSize();
}


/**
* @deprecated Since 2.5: replaced by a fluent form of the method; {@link #setMixIns}.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,21 @@
import java.text.DateFormat;
import java.util.*;

import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.PropertyAccessor;

import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.cfg.BaseSettings;
import com.fasterxml.jackson.databind.cfg.ContextAttributes;
import com.fasterxml.jackson.databind.cfg.HandlerInstantiator;
import com.fasterxml.jackson.databind.cfg.MapperConfigBase;

import com.fasterxml.jackson.databind.cfg.*;
import com.fasterxml.jackson.databind.introspect.ClassIntrospector;
import com.fasterxml.jackson.databind.introspect.SimpleMixInResolver;
import com.fasterxml.jackson.databind.introspect.VisibilityChecker;
import com.fasterxml.jackson.databind.jsontype.SubtypeResolver;
import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.SerializerFactory;
import com.fasterxml.jackson.databind.type.ClassKey;
import com.fasterxml.jackson.databind.type.TypeFactory;

/**
Expand Down Expand Up @@ -79,7 +80,7 @@ public final class SerializationConfig
* Constructor used by ObjectMapper to create default configuration object instance.
*/
public SerializationConfig(BaseSettings base,
SubtypeResolver str, Map<ClassKey,Class<?>> mixins)
SubtypeResolver str, SimpleMixInResolver mixins)
{
super(base, str, mixins);
_serFeatures = collectFeatureDefaults(SerializationFeature.class);
Expand Down Expand Up @@ -163,7 +164,7 @@ private SerializationConfig(SerializationConfig src, String rootName)
/**
* @since 2.1
*/
protected SerializationConfig(SerializationConfig src, Map<ClassKey,Class<?>> mixins)
protected SerializationConfig(SerializationConfig src, SimpleMixInResolver mixins)
{
super(src, mixins);
_serFeatures = src._serFeatures;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,19 @@
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.introspect.ClassIntrospector;
import com.fasterxml.jackson.databind.introspect.ClassIntrospector.MixInResolver;
import com.fasterxml.jackson.databind.introspect.SimpleMixInResolver;
import com.fasterxml.jackson.databind.introspect.VisibilityChecker;
import com.fasterxml.jackson.databind.jsontype.SubtypeResolver;
import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder;
import com.fasterxml.jackson.databind.type.ClassKey;
import com.fasterxml.jackson.databind.type.TypeFactory;

@SuppressWarnings("serial")
public abstract class MapperConfigBase<CFG extends ConfigFeature,
T extends MapperConfigBase<CFG,T>>
extends MapperConfig<T>
implements java.io.Serializable
{
private static final long serialVersionUID = 6062961959359172474L;

private final static int DEFAULT_MAPPER_FEATURES = collectFeatureDefaults(MapperFeature.class);

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

/**
* Registered concrete subtypes that can be used instead of (or
Expand Down Expand Up @@ -79,10 +81,10 @@ public abstract class MapperConfigBase<CFG extends ConfigFeature,
* that of creating fluent copies)
*/
protected MapperConfigBase(BaseSettings base,
SubtypeResolver str, Map<ClassKey,Class<?>> mixins)
SubtypeResolver str, SimpleMixInResolver mixins)
{
super(base, DEFAULT_MAPPER_FEATURES);
_mixInAnnotations = mixins;
_mixIns = mixins;
_subtypeResolver = str;
_rootName = null;
_view = null;
Expand All @@ -97,7 +99,7 @@ protected MapperConfigBase(BaseSettings base,
protected MapperConfigBase(MapperConfigBase<CFG,T> src)
{
super(src);
_mixInAnnotations = src._mixInAnnotations;
_mixIns = src._mixIns;
_subtypeResolver = src._subtypeResolver;
_rootName = src._rootName;
_view = src._view;
Expand All @@ -107,7 +109,7 @@ protected MapperConfigBase(MapperConfigBase<CFG,T> src)
protected MapperConfigBase(MapperConfigBase<CFG,T> src, BaseSettings base)
{
super(base, src._mapperFeatures);
_mixInAnnotations = src._mixInAnnotations;
_mixIns = src._mixIns;
_subtypeResolver = src._subtypeResolver;
_rootName = src._rootName;
_view = src._view;
Expand All @@ -117,7 +119,7 @@ protected MapperConfigBase(MapperConfigBase<CFG,T> src, BaseSettings base)
protected MapperConfigBase(MapperConfigBase<CFG,T> src, int mapperFeatures)
{
super(src._base, mapperFeatures);
_mixInAnnotations = src._mixInAnnotations;
_mixIns = src._mixIns;
_subtypeResolver = src._subtypeResolver;
_rootName = src._rootName;
_view = src._view;
Expand All @@ -126,7 +128,7 @@ protected MapperConfigBase(MapperConfigBase<CFG,T> src, int mapperFeatures)

protected MapperConfigBase(MapperConfigBase<CFG,T> src, SubtypeResolver str) {
super(src);
_mixInAnnotations = src._mixInAnnotations;
_mixIns = src._mixIns;
_subtypeResolver = str;
_rootName = src._rootName;
_view = src._view;
Expand All @@ -135,7 +137,7 @@ protected MapperConfigBase(MapperConfigBase<CFG,T> src, SubtypeResolver str) {

protected MapperConfigBase(MapperConfigBase<CFG,T> src, String rootName) {
super(src);
_mixInAnnotations = src._mixInAnnotations;
_mixIns = src._mixIns;
_subtypeResolver = src._subtypeResolver;
_rootName = rootName;
_view = src._view;
Expand All @@ -145,7 +147,7 @@ protected MapperConfigBase(MapperConfigBase<CFG,T> src, String rootName) {
protected MapperConfigBase(MapperConfigBase<CFG,T> src, Class<?> view)
{
super(src);
_mixInAnnotations = src._mixInAnnotations;
_mixIns = src._mixIns;
_subtypeResolver = src._subtypeResolver;
_rootName = src._rootName;
_view = view;
Expand All @@ -155,10 +157,10 @@ protected MapperConfigBase(MapperConfigBase<CFG,T> src, Class<?> view)
/**
* @since 2.1
*/
protected MapperConfigBase(MapperConfigBase<CFG,T> src, Map<ClassKey,Class<?>> mixins)
protected MapperConfigBase(MapperConfigBase<CFG,T> src, SimpleMixInResolver mixins)
{
super(src);
_mixInAnnotations = mixins;
_mixIns = mixins;
_subtypeResolver = src._subtypeResolver;
_rootName = src._rootName;
_view = src._view;
Expand All @@ -171,7 +173,7 @@ protected MapperConfigBase(MapperConfigBase<CFG,T> src, Map<ClassKey,Class<?>> m
protected MapperConfigBase(MapperConfigBase<CFG,T> src, ContextAttributes attr)
{
super(src);
_mixInAnnotations = src._mixInAnnotations;
_mixIns = src._mixIns;
_subtypeResolver = src._subtypeResolver;
_rootName = src._rootName;
_view = src._view;
Expand Down Expand Up @@ -401,10 +403,20 @@ public final ContextAttributes getAttributes() {
*/
@Override
public final Class<?> findMixInClassFor(Class<?> cls) {
return (_mixInAnnotations == null) ? null : _mixInAnnotations.get(new ClassKey(cls));
return _mixIns.findMixInClassFor(cls);
}

// Not really relevant here (should not get called)
@Override
public MixInResolver copy() {
throw new UnsupportedOperationException();
}

/**
* Test-only method -- does not reflect possibly open-ended set that external
* mix-in resolver might provide.
*/
public final int mixInCount() {
return (_mixInAnnotations == null) ? 0 : _mixInAnnotations.size();
return _mixIns.localSize();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ public interface MixInResolver
* annotations) for given class
*/
public Class<?> findMixInClassFor(Class<?> cls);

/**
* Method called to create a new, non-shared copy, to be used by different
* <code>ObjectMapper</code> instance, and one that should not be connected
* to this instance, if resolver has mutable state.
* If resolver is immutable may simply return `this`.
*
* @since 2.6
*/
public MixInResolver copy();
}

protected ClassIntrospector() { }
Expand Down
Loading

0 comments on commit 57b287f

Please sign in to comment.