MixInHandler.java
package tools.jackson.databind.introspect;
import java.util.HashMap;
import java.util.Map;
import tools.jackson.core.util.Snapshottable;
import tools.jackson.databind.type.ClassKey;
/**
* Basic {@link MixInResolver} implementation that both allows simple "local"
* override definitions (with simple Mix-in class over Target class mapping)
* and allows optional custom overrides for lookup.
*<p>
* Implementation is only thread-safe after initialization (that is,
* when underlying Map is not modified but only read).
*/
public class MixInHandler
implements MixInResolver,
java.io.Serializable
{
private static final long serialVersionUID = 1L;
/**
* External resolver that gets called before looking at any locally defined
* mix-in target classes.
*/
protected final MixInResolver _overrides;
/**
* Simple mix-in targets defined locally.
*/
protected Map<ClassKey,Class<?>> _localMixIns;
/*
/**********************************************************************
/* Construction, mutant factories
/**********************************************************************
*/
public MixInHandler(MixInResolver overrides) {
_overrides = overrides;
}
protected MixInHandler(MixInResolver overrides,
Map<ClassKey,Class<?>> mixins) {
_overrides = overrides;
_localMixIns = mixins;
}
/**
* Mutant factory for constructor a new resolver instance with given
* mix-in resolver override.
*/
public MixInHandler withOverrides(MixInResolver overrides) {
return new MixInHandler(overrides, _localMixIns);
}
/**
* Mutant factory method that constructs a new instance that has no locally
* defined mix-in/target mappings.
*/
public MixInHandler withoutLocalDefinitions() {
return new MixInHandler(_overrides, null);
}
/*
/**********************************************************************
/* Mutators
/**********************************************************************
*/
public MixInHandler addLocalDefinitions(Map<Class<?>, Class<?>> sourceMixins) {
if (!sourceMixins.isEmpty()) {
if (_localMixIns == null) {
_localMixIns = new HashMap<>(sourceMixins.size());
}
for (Map.Entry<Class<?>,Class<?>> en : sourceMixins.entrySet()) {
_localMixIns.put(new ClassKey(en.getKey()), en.getValue());
}
}
return this;
}
public MixInHandler addLocalDefinition(Class<?> target, Class<?> mixinSource) {
if (_localMixIns == null) {
_localMixIns = new HashMap<ClassKey,Class<?>>();
}
_localMixIns.put(new ClassKey(target), mixinSource);
return this;
}
public MixInHandler clearLocalDefinitions(Map<Class<?>, Class<?>> sourceMixins) {
_localMixIns = null;
return this;
}
/*
/**********************************************************************
/* MixInResolver API implementation
/**********************************************************************
*/
@Override
public MixInHandler snapshot() {
MixInResolver overrides = Snapshottable.takeSnapshot(_overrides);
Map<ClassKey,Class<?>> mixIns = (_localMixIns == null)
? null : new HashMap<ClassKey,Class<?>>(_localMixIns);
return new MixInHandler(overrides, mixIns);
}
@Override
public Class<?> findMixInClassFor(Class<?> cls)
{
Class<?> mixin = (_overrides == null) ? null : _overrides.findMixInClassFor(cls);
if (mixin == null && (_localMixIns != null)) {
mixin = _localMixIns.get(new ClassKey(cls));
}
return mixin;
}
@Override
public boolean hasMixIns() {
return (_localMixIns != null)
|| ((_overrides != null) && _overrides.hasMixIns());
}
/*
/**********************************************************************
/* Other
/**********************************************************************
*/
public int localSize() { // for tests
return (_localMixIns == null) ? 0 : _localMixIns.size();
}
}