use of com.fasterxml.jackson.databind.JavaType in project jackson-databind by FasterXML.
the class TypeFactory method constructGeneralizedType.
/**
* Method similar to {@link #constructSpecializedType}, but that creates a
* less-specific type of given type. Usually this is as simple as simply
* finding super-type with type erasure of <code>superClass</code>, but
* there may be need for some additional work-arounds.
*
* @param superClass
*
* @since 2.7
*/
public JavaType constructGeneralizedType(JavaType baseType, Class<?> superClass) {
// simple optimization to avoid costly introspection if type-erased type does NOT differ
final Class<?> rawBase = baseType.getRawClass();
if (rawBase == superClass) {
return baseType;
}
JavaType superType = baseType.findSuperType(superClass);
if (superType == null) {
// Most likely, caller did not verify sub/super-type relationship
if (!superClass.isAssignableFrom(rawBase)) {
throw new IllegalArgumentException(String.format("Class %s not a super-type of %s", superClass.getName(), baseType));
}
// 01-Nov-2015, tatu: Should never happen, but ch
throw new IllegalArgumentException(String.format("Internal error: class %s not included as super-type for %s", superClass.getName(), baseType));
}
return superType;
}
use of com.fasterxml.jackson.databind.JavaType in project jackson-databind by FasterXML.
the class TypeFactory method constructSpecializedType.
/*
/**********************************************************
/* Type conversion, parameterization resolution methods
/**********************************************************
*/
/**
* Factory method for creating a subtype of given base type, as defined
* by specified subclass; but retaining generic type information if any.
* Can be used, for example, to get equivalent of "HashMap<String,Integer>"
* from "Map<String,Integer>" by giving <code>HashMap.class</code>
* as subclass.
*/
public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass) {
// simple optimization to avoid costly introspection if type-erased type does NOT differ
final Class<?> rawBase = baseType.getRawClass();
if (rawBase == subclass) {
return baseType;
}
JavaType newType;
// also: if we start from untyped, not much to save
do {
// bogus loop to be able to break
if (rawBase == Object.class) {
newType = _fromClass(null, subclass, TypeBindings.emptyBindings());
break;
}
if (!rawBase.isAssignableFrom(subclass)) {
throw new IllegalArgumentException(String.format("Class %s not subtype of %s", subclass.getName(), baseType));
}
// (1) Original target type has no generics -- just resolve subtype
if (baseType.getBindings().isEmpty()) {
newType = _fromClass(null, subclass, TypeBindings.emptyBindings());
break;
}
// (2) A small set of "well-known" List/Map subtypes where can take a short-cut
if (baseType.isContainerType()) {
if (baseType.isMapLikeType()) {
if ((subclass == HashMap.class) || (subclass == LinkedHashMap.class) || (subclass == EnumMap.class) || (subclass == TreeMap.class)) {
newType = _fromClass(null, subclass, TypeBindings.create(subclass, baseType.getKeyType(), baseType.getContentType()));
break;
}
} else if (baseType.isCollectionLikeType()) {
if ((subclass == ArrayList.class) || (subclass == LinkedList.class) || (subclass == HashSet.class) || (subclass == TreeSet.class)) {
newType = _fromClass(null, subclass, TypeBindings.create(subclass, baseType.getContentType()));
break;
}
// but they are impl details and we basically do not care...
if (rawBase == EnumSet.class) {
return baseType;
}
}
}
// (3) Sub-class does not take type parameters -- just resolve subtype
int typeParamCount = subclass.getTypeParameters().length;
if (typeParamCount == 0) {
newType = _fromClass(null, subclass, TypeBindings.emptyBindings());
break;
}
// If not, we'll need to do more thorough forward+backwards resolution. Sigh.
// 20-Oct-2015, tatu: Container, Map-types somewhat special. There is
// a way to fully resolve and merge hierarchies; but that gets expensive
// so let's, for now, try to create close-enough approximation that
// is not 100% same, structurally, but has equivalent information for
// our specific neeeds.
// 29-Mar-2016, tatu: See [databind#1173] (and test `TypeResolverTest`)
// for a case where this code does get invoked: not ideal
// 29-Jun-2016, tatu: As to bindings, this works for [databind#1215], but
// not certain it would reliably work... but let's hope for best for now
TypeBindings tb = _bindingsForSubtype(baseType, typeParamCount, subclass);
if (baseType.isInterface()) {
newType = baseType.refine(subclass, tb, null, new JavaType[] { baseType });
} else {
newType = baseType.refine(subclass, tb, baseType, NO_TYPES);
}
// Only SimpleType returns null, but if so just resolve regularly
if (newType == null) {
newType = _fromClass(null, subclass, tb);
}
} while (false);
// 25-Sep-2016, tatu: As per [databind#1384] also need to ensure handlers get
// copied as well
newType = newType.withHandlersFrom(baseType);
return newType;
// 20-Oct-2015, tatu: Old simplistic approach
/*
// Currently mostly SimpleType instances can become something else
if (baseType instanceof SimpleType) {
// and only if subclass is an array, Collection or Map
if (subclass.isArray()
|| Map.class.isAssignableFrom(subclass)
|| Collection.class.isAssignableFrom(subclass)) {
// need to assert type compatibility...
if (!baseType.getRawClass().isAssignableFrom(subclass)) {
throw new IllegalArgumentException("Class "+subclass.getClass().getName()+" not subtype of "+baseType);
}
// this _should_ work, right?
JavaType subtype = _fromClass(null, subclass, TypeBindings.emptyBindings());
// one more thing: handlers to copy?
Object h = baseType.getValueHandler();
if (h != null) {
subtype = subtype.withValueHandler(h);
}
h = baseType.getTypeHandler();
if (h != null) {
subtype = subtype.withTypeHandler(h);
}
return subtype;
}
}
// But there is the need for special case for arrays too, it seems
if (baseType instanceof ArrayType) {
if (subclass.isArray()) {
// actually see if it might be a no-op first:
ArrayType at = (ArrayType) baseType;
Class<?> rawComp = subclass.getComponentType();
if (at.getContentType().getRawClass() == rawComp) {
return baseType;
}
JavaType componentType = _fromAny(null, rawComp, null);
return ((ArrayType) baseType).withComponentType(componentType);
}
}
// otherwise regular narrowing should work just fine
return baseType.narrowBy(subclass);
*/
}
use of com.fasterxml.jackson.databind.JavaType in project jackson-databind by FasterXML.
the class TypeFactory method _fromAny.
/*
/**********************************************************
/* Actual type resolution, traversal
/**********************************************************
*/
/**
* Factory method that can be used if type information is passed
* as Java typing returned from <code>getGenericXxx</code> methods
* (usually for a return or argument type).
*/
protected JavaType _fromAny(ClassStack context, Type type, TypeBindings bindings) {
JavaType resultType;
// simple class?
if (type instanceof Class<?>) {
// Important: remove possible bindings since this is type-erased thingy
resultType = _fromClass(context, (Class<?>) type, EMPTY_BINDINGS);
} else // But if not, need to start resolving.
if (type instanceof ParameterizedType) {
resultType = _fromParamType(context, (ParameterizedType) type, bindings);
} else if (type instanceof JavaType) {
// no need to modify further if we already had JavaType
return (JavaType) type;
} else if (type instanceof GenericArrayType) {
resultType = _fromArrayType(context, (GenericArrayType) type, bindings);
} else if (type instanceof TypeVariable<?>) {
resultType = _fromVariable(context, (TypeVariable<?>) type, bindings);
} else if (type instanceof WildcardType) {
resultType = _fromWildcard(context, (WildcardType) type, bindings);
} else {
// sanity check
throw new IllegalArgumentException("Unrecognized Type: " + ((type == null) ? "[null]" : type.toString()));
}
/* 21-Feb-2016, nateB/tatu: as per [databind#1129] (applied for 2.7.2),
* we do need to let all kinds of types to be refined, esp. for Scala module.
*/
if (_modifiers != null) {
TypeBindings b = resultType.getBindings();
if (b == null) {
b = EMPTY_BINDINGS;
}
for (TypeModifier mod : _modifiers) {
JavaType t = mod.modifyType(resultType, type, b, this);
if (t == null) {
throw new IllegalStateException(String.format("TypeModifier %s (of type %s) return null for type %s", mod, mod.getClass().getName(), resultType));
}
resultType = t;
}
}
return resultType;
}
use of com.fasterxml.jackson.databind.JavaType in project jackson-databind by FasterXML.
the class TypeParser method parse.
public JavaType parse(String canonical) throws IllegalArgumentException {
canonical = canonical.trim();
MyTokenizer tokens = new MyTokenizer(canonical);
JavaType type = parseType(tokens);
// must be end, now
if (tokens.hasMoreTokens()) {
throw _problem(tokens, "Unexpected tokens after complete type");
}
return type;
}
use of com.fasterxml.jackson.databind.JavaType in project jackson-databind by FasterXML.
the class ClassUtil method _addSuperTypes.
private static void _addSuperTypes(JavaType type, Class<?> endBefore, Collection<JavaType> result, boolean addClassItself) {
if (type == null) {
return;
}
final Class<?> cls = type.getRawClass();
if (cls == endBefore || cls == Object.class) {
return;
}
if (addClassItself) {
if (result.contains(type)) {
// already added, no need to check supers
return;
}
result.add(type);
}
for (JavaType intCls : type.getInterfaces()) {
_addSuperTypes(intCls, endBefore, result, true);
}
_addSuperTypes(type.getSuperClass(), endBefore, result, true);
}
Aggregations