public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (source == null) {
return this.conversionService.convertNullSource(sourceType, targetType);
}
Map<?, ?> sourceMap = (Map<?, ?>) source;
TypeDescriptor targetKeyType = targetType.getMapKeyTypeDescriptor();
TypeDescriptor targetValueType = targetType.getMapValueTypeDescriptor();
if (targetKeyType == TypeDescriptor.NULL && targetValueType == TypeDescriptor.NULL) {
return compatibleMapWithoutEntryConversion(sourceMap, targetType);
}
TypeDescriptor sourceKeyType = sourceType.getMapKeyTypeDescriptor();
TypeDescriptor sourceValueType = sourceType.getMapValueTypeDescriptor();
if (sourceKeyType == TypeDescriptor.NULL || sourceValueType == TypeDescriptor.NULL) {
TypeDescriptor[] sourceEntryTypes = ConversionUtils.getMapEntryTypes(sourceMap);
sourceKeyType = sourceEntryTypes[0];
sourceValueType = sourceEntryTypes[1];
}
if (sourceKeyType == TypeDescriptor.NULL && sourceValueType == TypeDescriptor.NULL) {
return compatibleMapWithoutEntryConversion(sourceMap, targetType);
}
boolean keysCompatible = false;
if (sourceKeyType != TypeDescriptor.NULL && sourceKeyType.isAssignableTo(targetKeyType)) {
keysCompatible = true;
}
boolean valuesCompatible = false;
if (sourceValueType != TypeDescriptor.NULL && sourceValueType.isAssignableTo(targetValueType)) {
valuesCompatible = true;
}
if (keysCompatible && valuesCompatible) {
return compatibleMapWithoutEntryConversion(sourceMap, targetType);
}