Skip to content

Commit 3e75d54

Browse files
committed
Refactoring for #1615
1 parent 581de93 commit 3e75d54

File tree

5 files changed

+63
-40
lines changed

5 files changed

+63
-40
lines changed

src/main/java/com/fasterxml/jackson/databind/DatabindContext.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,52 @@ public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass) {
161161
return getConfig().constructSpecializedType(baseType, subclass);
162162
}
163163

164+
/**
165+
* Lookup method called when code needs to resolve class name from input;
166+
* usually simple lookup
167+
*
168+
* @since 2.9
169+
*/
170+
public JavaType resolveSubType(JavaType baseType, String subClass)
171+
throws JsonMappingException
172+
{
173+
// 30-Jan-2010, tatu: Most ids are basic class names; so let's first
174+
// check if any generics info is added; and only then ask factory
175+
// to do translation when necessary
176+
if (subClass.indexOf('<') > 0) {
177+
// note: may want to try combining with specialization (esp for EnumMap)?
178+
return getTypeFactory().constructFromCanonical(subClass);
179+
}
180+
Class<?> cls;
181+
try {
182+
cls = getTypeFactory().findClass(subClass);
183+
} catch (ClassNotFoundException e) { // let caller handle this problem
184+
return null;
185+
} catch (Exception e) {
186+
throw invalidTypeIdException(baseType, subClass, String.format(
187+
"problem: (%s) %s",
188+
e.getClass().getName(), e.getMessage()));
189+
}
190+
if (baseType.isTypeOrSuperTypeOf(cls)) {
191+
return getTypeFactory().constructSpecializedType(baseType, cls);
192+
}
193+
throw invalidTypeIdException(baseType, subClass, "Not a subtype");
194+
}
195+
196+
/**
197+
* Helper method for constructing exception to indicate that given type id
198+
* could not be resolved to a valid subtype of specified base type.
199+
* Most commonly called during polymorphic deserialization.
200+
*<p>
201+
* Note that most of the time this method should NOT be called directly: instead,
202+
* method <code>handleUnknownTypeId()</code> should be called which will call this method
203+
* if necessary.
204+
*
205+
* @since 2.9
206+
*/
207+
protected abstract JsonMappingException invalidTypeIdException(JavaType baseType, String typeId,
208+
String extraDesc);
209+
164210
public abstract TypeFactory getTypeFactory();
165211

166212
/*

src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1558,17 +1558,7 @@ public JsonMappingException instantiationException(Class<?> instClass, String ms
15581558
return InvalidDefinitionException.from(_parser, msg, type);
15591559
}
15601560

1561-
/**
1562-
* Helper method for constructing exception to indicate that given type id
1563-
* could not be resolved to a valid subtype of specified base type, during
1564-
* polymorphic deserialization.
1565-
*<p>
1566-
* Note that most of the time this method should NOT be called; instead,
1567-
* {@link #handleUnknownTypeId} should be called which will call this method
1568-
* if necessary.
1569-
*
1570-
* @since 2.9
1571-
*/
1561+
@Override
15721562
public JsonMappingException invalidTypeIdException(JavaType baseType, String typeId,
15731563
String extraDesc) {
15741564
String msg = String.format("Could not resolve type id '%s' as a subtype of %s",

src/main/java/com/fasterxml/jackson/databind/SerializerProvider.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import com.fasterxml.jackson.databind.cfg.ContextAttributes;
1414
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
1515
import com.fasterxml.jackson.databind.exc.InvalidDefinitionException;
16+
import com.fasterxml.jackson.databind.exc.InvalidTypeIdException;
1617
import com.fasterxml.jackson.databind.introspect.Annotated;
1718
import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
1819
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
@@ -1222,6 +1223,14 @@ public void reportMappingProblem(Throwable t, String message, Object... msgArgs)
12221223
throw JsonMappingException.from(getGenerator(), message, t);
12231224
}
12241225

1226+
@Override
1227+
public JsonMappingException invalidTypeIdException(JavaType baseType, String typeId,
1228+
String extraDesc) {
1229+
String msg = String.format("Could not resolve type id '%s' as a subtype of %s",
1230+
typeId, baseType);
1231+
return InvalidTypeIdException.from(null, _colonConcat(msg, extraDesc), baseType, typeId);
1232+
}
1233+
12251234
/*
12261235
/********************************************************
12271236
/* Error reporting, deprecated methods

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

Lines changed: 5 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -39,42 +39,20 @@ public String idFromValueAndType(Object value, Class<?> type) {
3939

4040
@Override
4141
public JavaType typeFromId(DatabindContext context, String id) throws IOException {
42-
return _typeFromId(id, (DeserializationContext) context);
42+
return _typeFromId(id, context);
4343
}
4444

4545
protected JavaType _typeFromId(String id, DatabindContext ctxt) throws IOException
4646
{
47-
/* 30-Jan-2010, tatu: Most ids are basic class names; so let's first
48-
* check if any generics info is added; and only then ask factory
49-
* to do translation when necessary
50-
*/
51-
TypeFactory tf = ctxt.getTypeFactory();
52-
if (id.indexOf('<') > 0) {
53-
// note: may want to try combining with specialization (esp for EnumMap)?
54-
return tf.constructFromCanonical(id);
55-
}
56-
Class<?> cls;
57-
try {
58-
cls = tf.findClass(id);
59-
} catch (ClassNotFoundException e) {
60-
// 24-May-2016, tatu: Ok, this is pretty ugly, but we should always get
61-
// DeserializationContext, just playing it safe
47+
JavaType t = ctxt.resolveSubType(_baseType, id);
48+
if (t == null) {
6249
if (ctxt instanceof DeserializationContext) {
63-
DeserializationContext dctxt = (DeserializationContext) ctxt;
6450
// First: we may have problem handlers that can deal with it?
65-
return dctxt.handleUnknownTypeId(_baseType, id, this, "no such class found");
51+
return ((DeserializationContext) ctxt).handleUnknownTypeId(_baseType, id, this, "no such class found");
6652
}
6753
// ... meaning that we really should never get here.
68-
return null;
69-
} catch (Exception e) {
70-
throw ((DeserializationContext) ctxt).invalidTypeIdException(_baseType, id, String.format(
71-
"Invalid type id, problem: (%s) %s",
72-
e.getClass().getName(), e.getMessage()));
73-
}
74-
if (_baseType.isTypeOrSuperTypeOf(cls)) {
75-
return tf.constructSpecializedType(_baseType, cls);
7654
}
77-
throw ((DeserializationContext) ctxt).invalidTypeIdException(_baseType, id, "Not a subtype");
55+
return t;
7856
}
7957

8058
/*

src/main/java/com/fasterxml/jackson/databind/type/TypeFactory.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,8 +302,8 @@ public Class<?> findClass(String className) throws ClassNotFoundException
302302
}
303303

304304
protected Class<?> classForName(String name, boolean initialize,
305-
ClassLoader loader) throws ClassNotFoundException {
306-
return Class.forName(name, true, loader);
305+
ClassLoader loader) throws ClassNotFoundException {
306+
return Class.forName(name, true, loader);
307307
}
308308

309309
protected Class<?> classForName(String name) throws ClassNotFoundException {

0 commit comments

Comments
 (0)