in nifi-extension-bundles/nifi-extension-utils/nifi-record-utils/nifi-standard-record-utils/src/main/java/org/apache/nifi/schema/validation/StandardSchemaValidator.java [182:300]
private boolean isTypeCorrect(final Object value, final DataType dataType) {
switch (dataType.getFieldType()) {
case ENUM:
if (!(value instanceof String)) {
return false;
}
final EnumDataType enumDataType = (EnumDataType) dataType;
final List<String> enumList = enumDataType.getEnums();
return enumList.contains(value);
case ARRAY:
if (!(value instanceof Object[])) {
return false;
}
final ArrayDataType arrayDataType = (ArrayDataType) dataType;
final DataType elementType = arrayDataType.getElementType();
final Object[] array = (Object[]) value;
for (final Object arrayVal : array) {
if (arrayVal == null && arrayDataType.isElementsNullable()) {
continue;
}
if (!isTypeCorrect(arrayVal, elementType)) {
return false;
}
}
return true;
case MAP:
if (value instanceof Map) {
final MapDataType mapDataType = (MapDataType) dataType;
final DataType valueDataType = mapDataType.getValueType();
final Map<?, ?> map = (Map<?, ?>) value;
for (final Object mapValue : map.values()) {
if (mapValue == null && mapDataType.isValuesNullable()) {
continue;
}
if (!isTypeCorrect(mapValue, valueDataType)) {
return false;
}
}
return true;
} else if (value instanceof Record) {
Record record = (Record) value;
final MapDataType mapDataType = (MapDataType) dataType;
final DataType valueDataType = mapDataType.getValueType();
for (final String fieldName : record.getRawFieldNames()) {
final Object fieldValue = record.getValue(fieldName);
if (!isTypeCorrect(fieldValue, valueDataType)) {
return false;
}
}
return true;
} else {
return false;
}
case RECORD:
return value instanceof Record;
case CHOICE:
final ChoiceDataType choiceDataType = (ChoiceDataType) dataType;
for (final DataType choice : choiceDataType.getPossibleSubTypes()) {
if (isTypeCorrect(value, choice)) {
return true;
}
}
return false;
case BOOLEAN:
return value instanceof Boolean;
case CHAR:
return value instanceof Character;
case DATE:
return value instanceof java.sql.Date;
case STRING:
return value instanceof String;
case TIME:
return value instanceof java.sql.Time;
case TIMESTAMP:
return value instanceof java.sql.Timestamp;
// Numeric data types
case BIGINT:
case LONG:
case INT:
case SHORT:
case BYTE:
return DataTypeUtils.isFittingNumberType(value, dataType.getFieldType());
case DOUBLE:
return DataTypeUtils.isFittingNumberType(value, dataType.getFieldType())
|| value instanceof Byte
|| value instanceof Short
|| value instanceof Integer
|| DataTypeUtils.isLongFitsToDouble(value)
|| DataTypeUtils.isBigIntFitsToDouble(value);
case FLOAT:
// Some readers do not provide float vs. double.
// We should consider if it makes sense to allow either a Float or a Double here or have
// a Reader indicate whether or not it supports higher precision, etc.
// Same goes for Short/Integer
return DataTypeUtils.isFittingNumberType(value, dataType.getFieldType())
|| value instanceof Byte
|| value instanceof Short
|| DataTypeUtils.isDoubleWithinFloatInterval(value)
|| DataTypeUtils.isIntegerFitsToFloat(value)
|| DataTypeUtils.isLongFitsToFloat(value)
|| DataTypeUtils.isBigIntFitsToFloat(value);
case DECIMAL:
return DataTypeUtils.isFittingNumberType(value, dataType.getFieldType())
|| value instanceof Byte
|| value instanceof Short
|| value instanceof Integer
|| value instanceof Long
|| value instanceof BigInteger;
}
return false;
}