private boolean isTypeCorrect()

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;
    }