Skip to content

Commit 0b30af1

Browse files
committed
Use Value class around TypeResolverBuilder
1 parent 8cabbd9 commit 0b30af1

File tree

4 files changed

+102
-13
lines changed

4 files changed

+102
-13
lines changed

src/main/java/com/fasterxml/jackson/databind/introspect/JacksonAnnotationIntrospector.java

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1531,7 +1531,7 @@ protected TypeResolverBuilder<?> _findTypeResolver(MapperConfig<?> config,
15311531
if (typeInfo.getIdType() == JsonTypeInfo.Id.NONE) {
15321532
return _constructNoTypeResolverBuilder();
15331533
}
1534-
b = _constructStdTypeResolverBuilder();
1534+
b = _constructStdTypeResolverBuilder(config, typeInfo, baseType);
15351535
}
15361536
// Does it define a custom type id resolver?
15371537
JsonTypeIdResolver idResInfo = _findAnnotation(ann, JsonTypeIdResolver.class);
@@ -1540,35 +1540,38 @@ protected TypeResolverBuilder<?> _findTypeResolver(MapperConfig<?> config,
15401540
if (idRes != null) {
15411541
idRes.init(baseType);
15421542
}
1543-
b = b.init(typeInfo.getIdType(), idRes);
15441543
// 13-Aug-2011, tatu: One complication; external id only works for properties;
15451544
// so if declared for a Class, we will need to map it to "PROPERTY"
15461545
// instead of "EXTERNAL_PROPERTY"
1547-
JsonTypeInfo.As inclusion = typeInfo.getInclusionType();
1548-
if (inclusion == JsonTypeInfo.As.EXTERNAL_PROPERTY && (ann instanceof AnnotatedClass)) {
1549-
inclusion = JsonTypeInfo.As.PROPERTY;
1546+
if (ann instanceof AnnotatedClass) {
1547+
JsonTypeInfo.As inclusion = typeInfo.getInclusionType();
1548+
if (inclusion == JsonTypeInfo.As.EXTERNAL_PROPERTY && (ann instanceof AnnotatedClass)) {
1549+
typeInfo = typeInfo.withInclusionType(JsonTypeInfo.As.PROPERTY);
1550+
}
15501551
}
1551-
b = b.inclusion(inclusion);
1552-
b = b.typeProperty(typeInfo.getPropertyName());
1553-
Class<?> defaultImpl = typeInfo.getDefaultImpl();
1554-
1552+
15551553
// 08-Dec-2014, tatu: To deprecate `JsonTypeInfo.None` we need to use other placeholder(s);
15561554
// and since `java.util.Void` has other purpose (to indicate "deser as null"), we'll instead
15571555
// use `JsonTypeInfo.class` itself. But any annotation type will actually do, as they have no
15581556
// valid use (cannot instantiate as default)
1557+
Class<?> defaultImpl = typeInfo.getDefaultImpl();
15591558
if (defaultImpl != null && defaultImpl != JsonTypeInfo.None.class && !defaultImpl.isAnnotation()) {
1560-
b = b.defaultImpl(defaultImpl);
1559+
typeInfo = typeInfo.withDefaultImpl(defaultImpl);
15611560
}
1562-
b = b.typeIdVisibility(typeInfo.getIdVisible());
1561+
1562+
b = b.init(typeInfo, idRes);
15631563
return b;
15641564
}
15651565

15661566
/**
15671567
* Helper method for constructing standard {@link TypeResolverBuilder}
15681568
* implementation.
1569+
*
1570+
* @since 2.16, backported from 3.0
15691571
*/
1570-
protected StdTypeResolverBuilder _constructStdTypeResolverBuilder() {
1571-
return new StdTypeResolverBuilder();
1572+
protected TypeResolverBuilder<?> _constructStdTypeResolverBuilder(MapperConfig<?> config,
1573+
JsonTypeInfo.Value typeInfo, JavaType baseType) {
1574+
return new StdTypeResolverBuilder(typeInfo);
15721575
}
15731576

15741577
/**

src/main/java/com/fasterxml/jackson/databind/jsontype/TypeResolverBuilder.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,21 @@ public TypeDeserializer buildTypeDeserializer(DeserializationConfig config,
9797
* but not necessarily)
9898
*/
9999
public T init(JsonTypeInfo.Id idType, TypeIdResolver res);
100+
101+
/**
102+
* Initialization method that is called right after constructing
103+
* the builder instance, in cases where information could not be
104+
* passed directly (for example when instantiated for an annotation)
105+
*
106+
* @param settings Configuration settings to apply.
107+
*
108+
* @return Resulting builder instance (usually this builder,
109+
* but not necessarily)
110+
*
111+
* @since 2.16
112+
*/
113+
public T init(JsonTypeInfo.Value settings, TypeIdResolver res);
114+
100115

101116
/*
102117
/**********************************************************

src/main/java/com/fasterxml/jackson/databind/jsontype/impl/StdTypeResolverBuilder.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ public class StdTypeResolverBuilder
3535
* Whether type id should be exposed to deserializers or not
3636
*/
3737
protected boolean _typeIdVisible = false;
38+
39+
protected Boolean _requireTypeIdForSubtypes;
3840

3941
/**
4042
* Default class to use in case type information is not available
@@ -54,6 +56,27 @@ public class StdTypeResolverBuilder
5456

5557
public StdTypeResolverBuilder() { }
5658

59+
public StdTypeResolverBuilder(JsonTypeInfo.Value settings) {
60+
if (settings != null) {
61+
_idType = settings.getIdType();
62+
if (_idType == null) {
63+
throw new IllegalArgumentException("idType cannot be null");
64+
}
65+
_includeAs = settings.getInclusionType();
66+
_typeProperty = _propName(settings.getPropertyName(), _idType);
67+
_typeIdVisible = settings.getIdVisible();
68+
_defaultImpl = settings.getDefaultImpl();
69+
_requireTypeIdForSubtypes = settings.getRequireTypeIdForSubtypes();
70+
}
71+
}
72+
73+
protected static String _propName(String propName, JsonTypeInfo.Id idType) {
74+
if (propName == null) {
75+
propName = idType.getDefaultPropertyName();
76+
}
77+
return propName;
78+
}
79+
5780
/**
5881
* @since 2.9
5982
*/
@@ -79,6 +102,7 @@ protected StdTypeResolverBuilder(StdTypeResolverBuilder base,
79102
_customIdResolver = base._customIdResolver;
80103

81104
_defaultImpl = defaultImpl;
105+
_requireTypeIdForSubtypes = base._requireTypeIdForSubtypes;
82106
}
83107

84108
public static StdTypeResolverBuilder noTypeInfoBuilder() {
@@ -99,6 +123,31 @@ public StdTypeResolverBuilder init(JsonTypeInfo.Id idType, TypeIdResolver idRes)
99123
return this;
100124
}
101125

126+
@Override
127+
public StdTypeResolverBuilder init(JsonTypeInfo.Value settings,
128+
TypeIdResolver idRes)
129+
{
130+
_customIdResolver = idRes;
131+
132+
if (settings != null) {
133+
_idType = settings.getIdType();
134+
if (_idType == null) {
135+
throw new IllegalArgumentException("idType cannot be null");
136+
}
137+
_includeAs = settings.getInclusionType();
138+
139+
// Let's also initialize property name as per idType default
140+
_typeProperty = settings.getPropertyName();
141+
if (_typeProperty == null) {
142+
_typeProperty = _idType.getDefaultPropertyName();
143+
}
144+
_typeIdVisible = settings.getIdVisible();
145+
_defaultImpl = settings.getDefaultImpl();
146+
_requireTypeIdForSubtypes = settings.getRequireTypeIdForSubtypes();
147+
}
148+
return this;
149+
}
150+
102151
@Override
103152
public TypeSerializer buildTypeSerializer(SerializationConfig config,
104153
JavaType baseType, Collection<NamedType> subtypes)

src/test/java/com/fasterxml/jackson/databind/ser/jdk/MapKeySerializationTest.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,28 @@ public void testUnWrappedMapWithDefaultType() throws Exception{
256256
assertEquals("{\"@type\":\"HashMap\",\"xxxB\":\"bar\"}", json);
257257
}
258258

259+
// [databind#838]
260+
public void testUnWrappedMapWithDefaultTypeWithValue() throws Exception {
261+
final ObjectMapper mapper = new ObjectMapper();
262+
SimpleModule mod = new SimpleModule("test");
263+
mod.addKeySerializer(ABC.class, new ABCKeySerializer());
264+
mapper.registerModule(mod);
265+
266+
TypeResolverBuilder<?> typer = ObjectMapper.DefaultTypeResolverBuilder.construct(
267+
ObjectMapper.DefaultTyping.NON_FINAL, mapper.getPolymorphicTypeValidator());
268+
JsonTypeInfo.Value typeInfo = JsonTypeInfo.Value.construct(JsonTypeInfo.Id.NAME, JsonTypeInfo.As.PROPERTY,
269+
null, null, true, null);
270+
typer.init(typeInfo, null);
271+
mapper.setDefaultTyping(typer);
272+
273+
Map<ABC, String> stuff = new HashMap<ABC, String>();
274+
stuff.put(ABC.B, "bar");
275+
String json = mapper.writerFor(new TypeReference<Map<ABC, String>>() {
276+
})
277+
.writeValueAsString(stuff);
278+
assertEquals("{\"@type\":\"HashMap\",\"xxxB\":\"bar\"}", json);
279+
}
280+
259281
// [databind#1552]
260282
public void testMapsWithBinaryKeys() throws Exception
261283
{

0 commit comments

Comments
 (0)