in core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/registry/CachingCodecRegistry.java [331:406]
protected GenericType<?> inspectType(@NonNull Object value, @Nullable DataType cqlType) {
if (value instanceof List) {
List<?> list = (List<?>) value;
if (list.isEmpty()) {
// Empty collections are always encoded the same way, so any element type will do
// in the absence of a CQL type. When the CQL type is known, we try to infer the best Java
// type.
return cqlType == null ? JAVA_TYPE_FOR_EMPTY_LISTS : inferJavaTypeFromCqlType(cqlType);
} else {
Object firstElement = list.get(0);
if (firstElement == null) {
throw new IllegalArgumentException(
"Can't infer list codec because the first element is null "
+ "(note that CQL does not allow null values in collections)");
}
GenericType<?> elementType =
inspectType(
firstElement, cqlType == null ? null : ((ContainerType) cqlType).getElementType());
return GenericType.listOf(elementType);
}
} else if (value instanceof Set) {
Set<?> set = (Set<?>) value;
if (set.isEmpty()) {
return cqlType == null ? JAVA_TYPE_FOR_EMPTY_SETS : inferJavaTypeFromCqlType(cqlType);
} else {
Object firstElement = set.iterator().next();
if (firstElement == null) {
throw new IllegalArgumentException(
"Can't infer set codec because the first element is null "
+ "(note that CQL does not allow null values in collections)");
}
GenericType<?> elementType =
inspectType(
firstElement, cqlType == null ? null : ((SetType) cqlType).getElementType());
return GenericType.setOf(elementType);
}
} else if (value instanceof Map) {
Map<?, ?> map = (Map<?, ?>) value;
if (map.isEmpty()) {
return cqlType == null ? JAVA_TYPE_FOR_EMPTY_MAPS : inferJavaTypeFromCqlType(cqlType);
} else {
Map.Entry<?, ?> firstEntry = map.entrySet().iterator().next();
Object firstKey = firstEntry.getKey();
Object firstValue = firstEntry.getValue();
if (firstKey == null || firstValue == null) {
throw new IllegalArgumentException(
"Can't infer map codec because the first key and/or value is null "
+ "(note that CQL does not allow null values in collections)");
}
GenericType<?> keyType =
inspectType(firstKey, cqlType == null ? null : ((MapType) cqlType).getKeyType());
GenericType<?> valueType =
inspectType(firstValue, cqlType == null ? null : ((MapType) cqlType).getValueType());
return GenericType.mapOf(keyType, valueType);
}
} else if (value instanceof CqlVector) {
CqlVector<?> vector = (CqlVector<?>) value;
if (vector.isEmpty()) {
return cqlType == null ? JAVA_TYPE_FOR_EMPTY_CQLVECTORS : inferJavaTypeFromCqlType(cqlType);
} else {
Object firstElement = vector.iterator().next();
if (firstElement == null) {
throw new IllegalArgumentException(
"Can't infer vector codec because the first element is null "
+ "(note that CQL does not allow null values in collections)");
}
GenericType<?> elementType =
inspectType(
firstElement, cqlType == null ? null : ((VectorType) cqlType).getElementType());
return GenericType.vectorOf(elementType);
}
} else {
// There's not much more we can do
return GenericType.of(value.getClass());
}
}