com.fasterxml.jackson.databind.jsontype.impl.ClassNameIdResolver Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ehcache Show documentation
Show all versions of ehcache Show documentation
Ehcache is an open source, standards-based cache used to boost performance,
offload the database and simplify scalability. Ehcache is robust, proven and full-featured and
this has made it the most widely-used Java-based cache.
package com.fasterxml.jackson.databind.jsontype.impl;
import java.io.IOException;
import java.util.*;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.databind.util.ClassUtil;
/**
* {@link com.fasterxml.jackson.databind.jsontype.TypeIdResolver} implementation
* that converts between fully-qualified
* Java class names and (JSON) Strings.
*/
public class ClassNameIdResolver
extends TypeIdResolverBase
{
private final static String JAVA_UTIL_PKG = "java.util.";
public ClassNameIdResolver(JavaType baseType, TypeFactory typeFactory) {
super(baseType, typeFactory);
}
@Override
public JsonTypeInfo.Id getMechanism() { return JsonTypeInfo.Id.CLASS; }
public void registerSubtype(Class type, String name) {
// not used with class name - based resolvers
}
@Override
public String idFromValue(Object value) {
return _idFrom(value, value.getClass(), _typeFactory);
}
@Override
public String idFromValueAndType(Object value, Class type) {
return _idFrom(value, type, _typeFactory);
}
@Override
public JavaType typeFromId(DatabindContext context, String id) throws IOException {
return _typeFromId(id, context);
}
protected JavaType _typeFromId(String id, DatabindContext ctxt) throws IOException
{
JavaType t = ctxt.resolveSubType(_baseType, id);
if (t == null) {
if (ctxt instanceof DeserializationContext) {
// First: we may have problem handlers that can deal with it?
return ((DeserializationContext) ctxt).handleUnknownTypeId(_baseType, id, this, "no such class found");
}
// ... meaning that we really should never get here.
}
return t;
}
/*
/**********************************************************
/* Internal methods
/**********************************************************
*/
protected String _idFrom(Object value, Class cls, TypeFactory typeFactory)
{
// Need to ensure that "enum subtypes" work too
if (Enum.class.isAssignableFrom(cls)) {
if (!cls.isEnum()) { // means that it's sub-class of base enum, so:
cls = cls.getSuperclass();
}
}
String str = cls.getName();
if (str.startsWith(JAVA_UTIL_PKG)) {
// 25-Jan-2009, tatu: There are some internal classes that we cannot access as is.
// We need better mechanism; for now this has to do...
// Enum sets and maps are problematic since we MUST know type of
// contained enums, to be able to deserialize.
// In addition, EnumSet is not a concrete type either
if (value instanceof EnumSet) { // Regular- and JumboEnumSet...
Class enumClass = ClassUtil.findEnumType((EnumSet) value);
// not optimal: but EnumSet is not a customizable type so this is sort of ok
str = typeFactory.constructCollectionType(EnumSet.class, enumClass).toCanonical();
} else if (value instanceof EnumMap) {
Class enumClass = ClassUtil.findEnumType((EnumMap) value);
Class valueClass = Object.class;
// not optimal: but EnumMap is not a customizable type so this is sort of ok
str = typeFactory.constructMapType(EnumMap.class, enumClass, valueClass).toCanonical();
}
// 10-Jan-2018, tatu: Up until 2.9.4 we used to have other conversions for `Collections.xxx()`
// and `Arrays.asList(...)`; but it was changed to be handled on receiving end instead
} else if (str.indexOf('$') >= 0) {
/* Other special handling may be needed for inner classes,
* The best way to handle would be to find 'hidden' constructor; pass parent
* value etc (which is actually done for non-anonymous static classes!),
* but that is just not possible due to various things. So, we will instead
* try to generalize type into something we will be more likely to be able
* construct.
*/
Class outer = ClassUtil.getOuterClass(cls);
if (outer != null) {
// one more check: let's actually not worry if the declared static type is
// non-static as well; if so, deserializer does have a chance at figuring it all out.
Class staticType = _baseType.getRawClass();
if (ClassUtil.getOuterClass(staticType) == null) {
// Is this always correct? Seems like it should be...
cls = _baseType.getRawClass();
str = cls.getName();
}
}
}
return str;
}
@Override
public String getDescForKnownTypeIds() {
return "class name used as type id";
}
}