Skip to content

Commit

Permalink
Refactoring for #1615
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed May 3, 2017
1 parent 581de93 commit 3e75d54
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 40 deletions.
46 changes: 46 additions & 0 deletions src/main/java/com/fasterxml/jackson/databind/DatabindContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,52 @@ public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass) {
return getConfig().constructSpecializedType(baseType, subclass);
}

/**
* Lookup method called when code needs to resolve class name from input;
* usually simple lookup
*
* @since 2.9
*/
public JavaType resolveSubType(JavaType baseType, String subClass)
throws JsonMappingException
{
// 30-Jan-2010, tatu: Most ids are basic class names; so let's first
// check if any generics info is added; and only then ask factory
// to do translation when necessary
if (subClass.indexOf('<') > 0) {
// note: may want to try combining with specialization (esp for EnumMap)?
return getTypeFactory().constructFromCanonical(subClass);
}
Class<?> cls;
try {
cls = getTypeFactory().findClass(subClass);
} catch (ClassNotFoundException e) { // let caller handle this problem
return null;
} catch (Exception e) {
throw invalidTypeIdException(baseType, subClass, String.format(
"problem: (%s) %s",
e.getClass().getName(), e.getMessage()));
}
if (baseType.isTypeOrSuperTypeOf(cls)) {
return getTypeFactory().constructSpecializedType(baseType, cls);
}
throw invalidTypeIdException(baseType, subClass, "Not a subtype");
}

/**
* Helper method for constructing exception to indicate that given type id
* could not be resolved to a valid subtype of specified base type.
* Most commonly called during polymorphic deserialization.
*<p>
* Note that most of the time this method should NOT be called directly: instead,
* method <code>handleUnknownTypeId()</code> should be called which will call this method
* if necessary.
*
* @since 2.9
*/
protected abstract JsonMappingException invalidTypeIdException(JavaType baseType, String typeId,
String extraDesc);

public abstract TypeFactory getTypeFactory();

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1558,17 +1558,7 @@ public JsonMappingException instantiationException(Class<?> instClass, String ms
return InvalidDefinitionException.from(_parser, msg, type);
}

/**
* Helper method for constructing exception to indicate that given type id
* could not be resolved to a valid subtype of specified base type, during
* polymorphic deserialization.
*<p>
* Note that most of the time this method should NOT be called; instead,
* {@link #handleUnknownTypeId} should be called which will call this method
* if necessary.
*
* @since 2.9
*/
@Override
public JsonMappingException invalidTypeIdException(JavaType baseType, String typeId,
String extraDesc) {
String msg = String.format("Could not resolve type id '%s' as a subtype of %s",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import com.fasterxml.jackson.databind.cfg.ContextAttributes;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.fasterxml.jackson.databind.exc.InvalidDefinitionException;
import com.fasterxml.jackson.databind.exc.InvalidTypeIdException;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
Expand Down Expand Up @@ -1222,6 +1223,14 @@ public void reportMappingProblem(Throwable t, String message, Object... msgArgs)
throw JsonMappingException.from(getGenerator(), message, t);
}

@Override
public JsonMappingException invalidTypeIdException(JavaType baseType, String typeId,
String extraDesc) {
String msg = String.format("Could not resolve type id '%s' as a subtype of %s",
typeId, baseType);
return InvalidTypeIdException.from(null, _colonConcat(msg, extraDesc), baseType, typeId);
}

/*
/********************************************************
/* Error reporting, deprecated methods
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,42 +39,20 @@ public String idFromValueAndType(Object value, Class<?> type) {

@Override
public JavaType typeFromId(DatabindContext context, String id) throws IOException {
return _typeFromId(id, (DeserializationContext) context);
return _typeFromId(id, context);
}

protected JavaType _typeFromId(String id, DatabindContext ctxt) throws IOException
{
/* 30-Jan-2010, tatu: Most ids are basic class names; so let's first
* check if any generics info is added; and only then ask factory
* to do translation when necessary
*/
TypeFactory tf = ctxt.getTypeFactory();
if (id.indexOf('<') > 0) {
// note: may want to try combining with specialization (esp for EnumMap)?
return tf.constructFromCanonical(id);
}
Class<?> cls;
try {
cls = tf.findClass(id);
} catch (ClassNotFoundException e) {
// 24-May-2016, tatu: Ok, this is pretty ugly, but we should always get
// DeserializationContext, just playing it safe
JavaType t = ctxt.resolveSubType(_baseType, id);
if (t == null) {
if (ctxt instanceof DeserializationContext) {
DeserializationContext dctxt = (DeserializationContext) ctxt;
// First: we may have problem handlers that can deal with it?
return dctxt.handleUnknownTypeId(_baseType, id, this, "no such class found");
return ((DeserializationContext) ctxt).handleUnknownTypeId(_baseType, id, this, "no such class found");
}
// ... meaning that we really should never get here.
return null;
} catch (Exception e) {
throw ((DeserializationContext) ctxt).invalidTypeIdException(_baseType, id, String.format(
"Invalid type id, problem: (%s) %s",
e.getClass().getName(), e.getMessage()));
}
if (_baseType.isTypeOrSuperTypeOf(cls)) {
return tf.constructSpecializedType(_baseType, cls);
}
throw ((DeserializationContext) ctxt).invalidTypeIdException(_baseType, id, "Not a subtype");
return t;
}

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -302,8 +302,8 @@ public Class<?> findClass(String className) throws ClassNotFoundException
}

protected Class<?> classForName(String name, boolean initialize,
ClassLoader loader) throws ClassNotFoundException {
return Class.forName(name, true, loader);
ClassLoader loader) throws ClassNotFoundException {
return Class.forName(name, true, loader);
}

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

0 comments on commit 3e75d54

Please sign in to comment.