protected TypeConverter doLookup(Class<?> toType, Class<?> fromType, boolean isSuper) {
if (fromType != null) {
// lets try if there is a direct match
TypeConverter converter = getTypeConverter(toType, fromType);
if (converter != null) {
return converter;
}
// try the interfaces
for (Class<?> type : fromType.getInterfaces()) {
converter = getTypeConverter(toType, type);
if (converter != null) {
return converter;
}
}
// try super then
Class<?> fromSuperClass = fromType.getSuperclass();
if (fromSuperClass != null && !fromSuperClass.equals(Object.class)) {
converter = doLookup(toType, fromSuperClass, true);
if (converter != null) {
return converter;
}
}
}
// only do these tests as fallback and only on the target type (eg not on its super)
if (!isSuper) {
if (fromType != null && !fromType.equals(Object.class)) {
// lets try classes derived from this toType
Set<Map.Entry<TypeMapping, TypeConverter>> entries = typeMappings.entrySet();
for (Map.Entry<TypeMapping, TypeConverter> entry : entries) {
TypeMapping key = entry.getKey();
Class<?> aToType = key.getToType();
if (toType.isAssignableFrom(aToType)) {
Class<?> aFromType = key.getFromType();
// skip Object based we do them last
if (!aFromType.equals(Object.class) && aFromType.isAssignableFrom(fromType)) {
return entry.getValue();
}
}
}
// lets test for Object based converters as last resort
TypeConverter converter = getTypeConverter(toType, Object.class);
if (converter != null) {
return converter;
}
}
}