Skip to content

Commit

Permalink
More refactoring for type handling
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Nov 2, 2015
1 parent 3243c9f commit 16ba95f
Show file tree
Hide file tree
Showing 12 changed files with 90 additions and 142 deletions.
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -765,6 +765,7 @@ public JavaType refineSerializationType(final MapperConfig<?> config,
final Annotated a, final JavaType baseType) throws JsonMappingException final Annotated a, final JavaType baseType) throws JsonMappingException
{ {
JavaType type = baseType; JavaType type = baseType;
final TypeFactory tf = config.getTypeFactory();


// 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to // 10-Oct-2015, tatu: For 2.7, we'll need to delegate back to
// now-deprecated secondary methods; this because while // now-deprecated secondary methods; this because while
Expand All @@ -776,7 +777,6 @@ public JavaType refineSerializationType(final MapperConfig<?> config,
// Ok: start by refining the main type itself; common to all types // Ok: start by refining the main type itself; common to all types
Class<?> serClass = findSerializationType(a); Class<?> serClass = findSerializationType(a);
if ((serClass != null) && !type.hasRawClass(serClass)) { if ((serClass != null) && !type.hasRawClass(serClass)) {
final TypeFactory tf = config.getTypeFactory();
try { try {
// 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`, // 11-Oct-2015, tatu: For deser, we call `TypeFactory.constructSpecializedType()`,
// may be needed here too in future? // may be needed here too in future?
Expand All @@ -792,10 +792,12 @@ public JavaType refineSerializationType(final MapperConfig<?> config,


// First, key type (for Maps, Map-like types): // First, key type (for Maps, Map-like types):
if (type.isMapLikeType()) { if (type.isMapLikeType()) {
Class<?> keyClass = findSerializationKeyType(a, type.getKeyType()); JavaType keyType = type.getKeyType();
Class<?> keyClass = findSerializationKeyType(a, keyType);
if (keyClass != null) { if (keyClass != null) {
try { try {
type = ((MapLikeType) type).widenKey(keyClass); keyType = tf.constructGeneralizedType(keyType, keyClass);
type = ((MapLikeType) type).withKeyType(keyType);
} catch (IllegalArgumentException iae) { } catch (IllegalArgumentException iae) {
throw new JsonMappingException(null, throw new JsonMappingException(null,
String.format("Failed to widen key type of %s with concrete-type annotation (value %s), from '%s': %s", String.format("Failed to widen key type of %s with concrete-type annotation (value %s), from '%s': %s",
Expand All @@ -804,16 +806,19 @@ public JavaType refineSerializationType(final MapperConfig<?> config,
} }
} }
} }
if (type.getContentType() != null) { // collection[like], map[like], array, reference
JavaType contentType = type.getContentType();
if (contentType != null) { // collection[like], map[like], array, reference
// And then value types for all containers: // And then value types for all containers:
Class<?> valueClass = findSerializationContentType(a, type.getContentType()); Class<?> contentClass = findSerializationContentType(a, type.getContentType());
if (valueClass != null) { if (contentClass != null) {
try { try {
type = type.widenContentsBy(valueClass); contentType = tf.constructGeneralizedType(contentType, contentClass);
type = type.withContentType(contentType);
} catch (IllegalArgumentException iae) { } catch (IllegalArgumentException iae) {
throw new JsonMappingException(null, throw new JsonMappingException(null,
String.format("Failed to widen value type of %s with concrete-type annotation (value %s), from '%s': %s", String.format("Failed to widen value type of %s with concrete-type annotation (value %s), from '%s': %s",
type, valueClass.getName(), a.getName(), iae.getMessage()), type, contentClass.getName(), a.getName(), iae.getMessage()),
iae); iae);
} }
} }
Expand Down
43 changes: 14 additions & 29 deletions src/main/java/com/fasterxml/jackson/databind/JavaType.java
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ protected JavaType(JavaType base)
public abstract JavaType withTypeHandler(Object h); public abstract JavaType withTypeHandler(Object h);


/** /**
* "Copy method" that will construct a new instance that is identical to * Mutant factory method that will construct a new instance that is identical to
* this instance, except that its content type will have specified * this instance, except that its content type will have specified
* type handler assigned. * type handler assigned.
* *
Expand All @@ -115,21 +115,32 @@ protected JavaType(JavaType base)
public abstract JavaType withContentTypeHandler(Object h); public abstract JavaType withContentTypeHandler(Object h);


/** /**
* "Copy method" that will construct a new instance that is identical to * Mutant factory method that will construct a new instance that is identical to
* this instance, except that it will have specified value handler assigned. * this instance, except that it will have specified value handler assigned.
* *
* @return Newly created type instance * @return Newly created type instance
*/ */
public abstract JavaType withValueHandler(Object h); public abstract JavaType withValueHandler(Object h);


/** /**
* "Copy method" that will construct a new instance that is identical to * Mutant factory method that will construct a new instance that is identical to
* this instance, except that it will have specified content value handler assigned. * this instance, except that it will have specified content value handler assigned.
* *
* @return Newly created type instance * @return Newly created type instance
*/ */
public abstract JavaType withContentValueHandler(Object h); public abstract JavaType withContentValueHandler(Object h);


/**
* Mutant factory method that will construct a new instance that is identical to
* this instance, except that it has specified content type, instead of current
* one. If content type is already set to given type, <code>this</code> is returned.
*
* @return Newly created type instance
*
* @since 2.7
*/
public abstract JavaType withContentType(JavaType contentType);

/** /**
* Method that can be called to get a type instance that indicates * Method that can be called to get a type instance that indicates
* that values of the type should be handled using "static typing" for purposes * that values of the type should be handled using "static typing" for purposes
Expand Down Expand Up @@ -197,36 +208,10 @@ public JavaType forcedNarrowBy(Class<?> subclass)
return result; return result;
} }


/**
* Method that can be called to do a "widening" conversions; that is,
* to return a type with a raw class that could be assigned from this
* type.
* If such conversion is not possible, an
* {@link IllegalArgumentException} is thrown.
* If class is same as the current raw class, instance itself is
* returned.
*/
public JavaType widenBy(Class<?> superclass) {
// First: if same raw class, just return this instance
if (superclass == _class) { return this; }
// Otherwise, ensure compatibility
_assertSubclass(_class, superclass);
return _widen(superclass);
}

protected abstract JavaType _narrow(Class<?> subclass); protected abstract JavaType _narrow(Class<?> subclass);


/**
*<p>
* Default implementation is just to call {@link #_narrow}, since
* underlying type construction is usually identical
*/
protected JavaType _widen(Class<?> superclass) { return _narrow(superclass); }

public abstract JavaType narrowContentsBy(Class<?> contentClass); public abstract JavaType narrowContentsBy(Class<?> contentClass);


public abstract JavaType widenContentsBy(Class<?> contentClass);

/** /**
* Mutant factory method that will try to create and return a sub-type instance * Mutant factory method that will try to create and return a sub-type instance
* for known parameterized types; for other types will return `null` to indicate * for known parameterized types; for other types will return `null` to indicate
Expand Down
21 changes: 5 additions & 16 deletions src/main/java/com/fasterxml/jackson/databind/type/ArrayType.java
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -47,13 +47,11 @@ public static ArrayType construct(JavaType componentType, TypeBindings bindings,
Object emptyInstance = Array.newInstance(componentType.getRawClass(), 0); Object emptyInstance = Array.newInstance(componentType.getRawClass(), 0);
return new ArrayType(componentType, bindings, emptyInstance, valueHandler, typeHandler, false); return new ArrayType(componentType, bindings, emptyInstance, valueHandler, typeHandler, false);
} }


/** @Override
* @since 2.7 public JavaType withContentType(JavaType contentType) {
*/ Object emptyInstance = Array.newInstance(contentType.getRawClass(), 0);
public ArrayType withOverriddenComponentType(JavaType componentType) { return new ArrayType(contentType, _bindings, emptyInstance,
Object emptyInstance = Array.newInstance(componentType.getRawClass(), 0);
return new ArrayType(componentType, _bindings, emptyInstance,
_valueHandler, _typeHandler, _asStatic); _valueHandler, _typeHandler, _asStatic);
} }


Expand Down Expand Up @@ -130,15 +128,6 @@ public JavaType narrowContentsBy(Class<?> contentClass) {
_valueHandler, _typeHandler); _valueHandler, _typeHandler);
} }


@Override
public JavaType widenContentsBy(Class<?> contentClass) {
if (contentClass == _componentType.getRawClass()) {
return this;
}
return construct(_componentType.narrowBy(contentClass), _bindings,
_valueHandler, _typeHandler);
}

// Should not be called, as array types in Java are not extensible; but // Should not be called, as array types in Java are not extensible; but
// let's not freak out even if it is called? // let's not freak out even if it is called?
@Override @Override
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -91,20 +91,16 @@ public JavaType narrowContentsBy(Class<?> contentClass)
} }


@Override @Override
public JavaType widenContentsBy(Class<?> contentClass) public JavaType withContentType(JavaType contentType) {
{ if (_elementType == contentType) {
// Can do a quick check first:
if (contentClass == _elementType.getRawClass()) {
return this; return this;
} }
return new CollectionLikeType(_class, _bindings, return new CollectionLikeType(_class, _bindings, _superClass, _superInterfaces,
_superClass, _superInterfaces, _elementType.widenBy(contentClass), contentType, _valueHandler, _typeHandler, _asStatic);
_valueHandler, _typeHandler, _asStatic);
} }

@Override @Override
public CollectionLikeType withTypeHandler(Object h) public CollectionLikeType withTypeHandler(Object h) {
{
return new CollectionLikeType(_class, _bindings, return new CollectionLikeType(_class, _bindings,
_superClass, _superInterfaces, _elementType, _valueHandler, h, _asStatic); _superClass, _superInterfaces, _elementType, _valueHandler, h, _asStatic);
} }
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -71,17 +71,14 @@ public JavaType narrowContentsBy(Class<?> contentClass)
} }


@Override @Override
public JavaType widenContentsBy(Class<?> contentClass) public JavaType withContentType(JavaType contentType) {
{ if (_elementType == contentType) {
// Can do a quick check first:
if (contentClass == _elementType.getRawClass()) {
return this; return this;
} }
return new CollectionType(_class, _bindings, return new CollectionType(_class, _bindings, _superClass, _superInterfaces,
_superClass, _superInterfaces, _elementType.widenBy(contentClass), contentType, _valueHandler, _typeHandler, _asStatic);
_valueHandler, _typeHandler, _asStatic);
} }

@Override @Override
public CollectionType withTypeHandler(Object h) { public CollectionType withTypeHandler(Object h) {
return new CollectionType(_class, _bindings, return new CollectionType(_class, _bindings,
Expand Down
40 changes: 18 additions & 22 deletions src/main/java/com/fasterxml/jackson/databind/type/MapLikeType.java
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -90,17 +90,6 @@ public JavaType narrowContentsBy(Class<?> contentClass)
_valueHandler, _typeHandler, _asStatic); _valueHandler, _typeHandler, _asStatic);
} }


@Override
public JavaType widenContentsBy(Class<?> contentClass)
{
if (contentClass == _valueType.getRawClass()) {
return this;
}
return new MapLikeType(_class, _bindings,
_superClass, _superInterfaces, _keyType, _valueType.widenBy(contentClass),
_valueHandler, _typeHandler, _asStatic);
}

public JavaType narrowKey(Class<?> keySubclass) public JavaType narrowKey(Class<?> keySubclass)
{ {
// Can do a quick check first: // Can do a quick check first:
Expand All @@ -112,27 +101,23 @@ public JavaType narrowKey(Class<?> keySubclass)
_valueHandler, _typeHandler, _asStatic); _valueHandler, _typeHandler, _asStatic);
} }


public JavaType widenKey(Class<?> keySubclass) @Override
{ public JavaType withContentType(JavaType contentType) {
// Can do a quick check first: if (_valueType == contentType) {
if (keySubclass == _keyType.getRawClass()) {
return this; return this;
} }
return new MapLikeType(_class, _bindings, return new MapLikeType(_class, _bindings, _superClass, _superInterfaces,
_superClass, _superInterfaces, _keyType.widenBy(keySubclass), _valueType, _keyType, contentType, _valueHandler, _typeHandler, _asStatic);
_valueHandler, _typeHandler, _asStatic);
} }


@Override @Override
public MapLikeType withTypeHandler(Object h) public MapLikeType withTypeHandler(Object h) {
{
return new MapLikeType(_class, _bindings, return new MapLikeType(_class, _bindings,
_superClass, _superInterfaces, _keyType, _valueType, _valueHandler, h, _asStatic); _superClass, _superInterfaces, _keyType, _valueType, _valueHandler, h, _asStatic);
} }


@Override @Override
public MapLikeType withContentTypeHandler(Object h) public MapLikeType withContentTypeHandler(Object h) {
{
return new MapLikeType(_class, _bindings, return new MapLikeType(_class, _bindings,
_superClass, _superInterfaces, _keyType, _valueType.withTypeHandler(h), _superClass, _superInterfaces, _keyType, _valueType.withTypeHandler(h),
_valueHandler, _typeHandler, _asStatic); _valueHandler, _typeHandler, _asStatic);
Expand Down Expand Up @@ -161,6 +146,17 @@ public MapLikeType withStaticTyping() {
_valueHandler, _typeHandler, true); _valueHandler, _typeHandler, true);
} }


/**
* @since 2.7
*/
public MapLikeType withKeyType(JavaType keyType) {
if (keyType == _keyType) {
return this;
}
return new MapLikeType(_class, _bindings, _superClass, _superInterfaces,
keyType, _valueType, _valueHandler, _typeHandler, _asStatic);
}

@Override @Override
public JavaType refine(Class<?> rawType, TypeBindings bindings, public JavaType refine(Class<?> rawType, TypeBindings bindings,
JavaType superClass, JavaType[] superInterfaces) { JavaType superClass, JavaType[] superInterfaces) {
Expand Down
41 changes: 18 additions & 23 deletions src/main/java/com/fasterxml/jackson/databind/type/MapType.java
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -63,17 +63,6 @@ public JavaType narrowContentsBy(Class<?> contentClass)
_valueHandler, _typeHandler, _asStatic); _valueHandler, _typeHandler, _asStatic);
} }


@Override
public JavaType widenContentsBy(Class<?> contentClass)
{
if (contentClass == _valueType.getRawClass()) {
return this;
}
return new MapType(_class, _bindings,
_superClass, _superInterfaces, _keyType, _valueType.widenBy(contentClass),
_valueHandler, _typeHandler, _asStatic);
}

@Override @Override
public JavaType narrowKey(Class<?> keySubclass) public JavaType narrowKey(Class<?> keySubclass)
{ {
Expand All @@ -86,18 +75,6 @@ public JavaType narrowKey(Class<?> keySubclass)
_valueHandler, _typeHandler, _asStatic); _valueHandler, _typeHandler, _asStatic);
} }


@Override
public JavaType widenKey(Class<?> keySubclass)
{
// Can do a quick check first:
if (keySubclass == _keyType.getRawClass()) {
return this;
}
return new MapType(_class, _bindings,
_superClass, _superInterfaces, _keyType.widenBy(keySubclass), _valueType,
_valueHandler, _typeHandler, _asStatic);
}

@Override @Override
public MapType withTypeHandler(Object h) { public MapType withTypeHandler(Object h) {
return new MapType(_class, _bindings, return new MapType(_class, _bindings,
Expand Down Expand Up @@ -135,6 +112,24 @@ public MapType withStaticTyping() {
_valueHandler, _typeHandler, true); _valueHandler, _typeHandler, true);
} }


@Override
public JavaType withContentType(JavaType contentType) {
if (_valueType == contentType) {
return this;
}
return new MapType(_class, _bindings, _superClass, _superInterfaces,
_keyType, contentType, _valueHandler, _typeHandler, _asStatic);
}

@Override
public MapType withKeyType(JavaType keyType) {
if (keyType == _keyType) {
return this;
}
return new MapType(_class, _bindings, _superClass, _superInterfaces,
keyType, _valueType, _valueHandler, _typeHandler, _asStatic);
}

@Override @Override
public JavaType refine(Class<?> rawType, TypeBindings bindings, public JavaType refine(Class<?> rawType, TypeBindings bindings,
JavaType superClass, JavaType[] superInterfaces) { JavaType superClass, JavaType[] superInterfaces) {
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -167,18 +167,6 @@ public JavaType narrowContentsBy(Class<?> contentClass)
_valueHandler, _typeHandler, _asStatic); _valueHandler, _typeHandler, _asStatic);
} }


@Override
public JavaType widenContentsBy(Class<?> contentClass)
{
// Can do a quick check first:
if (contentClass == _referencedType.getRawClass()) {
return this;
}
return new ReferenceType(_class, _bindings,
_superClass, _superInterfaces, _referencedType.widenBy(contentClass),
_valueHandler, _typeHandler, _asStatic);
}

/* /*
/********************************************************** /**********************************************************
/* Public API overrides /* Public API overrides
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ public StringBuilder getErasedSignature(StringBuilder sb) {
return _referencedType.getErasedSignature(sb); return _referencedType.getErasedSignature(sb);
} }


@Override
public JavaType withContentType(JavaType contentType) {
return this;
}

@Override @Override
public JavaType withTypeHandler(Object h) { public JavaType withTypeHandler(Object h) {
return this; return this;
Expand Down Expand Up @@ -73,11 +78,6 @@ public JavaType narrowContentsBy(Class<?> contentClass) {
return this; return this;
} }


@Override
public JavaType widenContentsBy(Class<?> contentClass) {
return this;
}

@Override @Override
public JavaType refine(Class<?> rawType, TypeBindings bindings, public JavaType refine(Class<?> rawType, TypeBindings bindings,
JavaType superClass, JavaType[] superInterfaces) { JavaType superClass, JavaType[] superInterfaces) {
Expand Down
Loading

0 comments on commit 16ba95f

Please sign in to comment.