in mapper-processor/src/main/java/com/datastax/oss/driver/internal/mapper/processor/util/generation/GeneratedCodePatterns.java [224:368]
public static void setValue(
CodeBlock cqlName,
PropertyType type,
CodeBlock valueExtractor,
String targetName,
CodeBlock.Builder methodBuilder,
BindableHandlingSharedCode enclosingClass,
boolean useNullSavingStrategy,
boolean useLeniency) {
if (type instanceof PropertyType.Simple) {
TypeName typeName = ((PropertyType.Simple) type).typeName;
String primitiveAccessor = GeneratedCodePatterns.PRIMITIVE_ACCESSORS.get(typeName);
if (primitiveAccessor != null) {
// Primitive type: use dedicated setter, since it is optimized to avoid boxing.
// target = target.setInt("length", entity.getLength());
methodBuilder.addStatement(
"$1L = $1L.set$2L($3L, $4L)",
targetName,
primitiveAccessor,
cqlName,
valueExtractor); // null saving strategy for primitiveSet does not apply
} else if (typeName instanceof ClassName) {
// Unparameterized class: use the generic, class-based setter.
// target = target.set("id", entity.getId(), UUID.class);
generateSetWithClass(
cqlName, valueExtractor, targetName, methodBuilder, typeName, useNullSavingStrategy);
} else {
// Parameterized type: create a constant and use the GenericType-based setter.
// private static final GenericType<List<String>> GENERIC_TYPE =
// new GenericType<List<String>>(){};
// target = target.set("names", entity.getNames(), GENERIC_TYPE);
// Note that lists, sets and maps of unparameterized classes also fall under that
// category. Their setter creates a GenericType under the hood, so there's no performance
// advantage in calling them instead of the generic set().
generateParameterizedSet(
cqlName,
valueExtractor,
targetName,
methodBuilder,
typeName,
enclosingClass,
useNullSavingStrategy);
}
} else if (type instanceof PropertyType.SingleEntity) {
ClassName entityClass = ((PropertyType.SingleEntity) type).entityName;
// Other entity class: the CQL column is a mapped UDT. Example of generated code:
// Dimensions value = entity.getDimensions();
// if (value != null) {
// UserDefinedType udtType = (UserDefinedType) target.getType("dimensions");
// UdtValue udtValue = udtType.newValue();
// dimensionsHelper.set(value, udtValue);
// target = target.setUdtValue("dimensions", udtValue);
// }
// Generate unique names for our temporary variables. Note that they are local so we don't
// strictly need class-wide uniqueness, but it's simpler to reuse the NameIndex
String udtTypeName = enclosingClass.getNameIndex().uniqueField("udtType");
String udtValueName = enclosingClass.getNameIndex().uniqueField("udtValue");
String valueName = enclosingClass.getNameIndex().uniqueField("value");
methodBuilder
.addStatement("$T $L = $L", entityClass, valueName, valueExtractor)
.beginControlFlow("if ($L != null)", valueName)
.addStatement(
"$1T $2L = ($1T) $3L.getType($4L)",
UserDefinedType.class,
udtTypeName,
targetName,
cqlName)
.addStatement("$T $L = $L.newValue()", UdtValue.class, udtValueName, udtTypeName);
String childHelper = enclosingClass.addEntityHelperField(entityClass);
methodBuilder
// driver doesn't have the ability to send partial UDT, unset values values will be
// serialized to null - set NullSavingStrategy.DO_NOT_SET explicitly
.addStatement(
"$L.set($L, $L, $T.$L, $L)",
childHelper,
valueName,
udtValueName,
NullSavingStrategy.class,
NullSavingStrategy.DO_NOT_SET,
useLeniency ? "lenient" : false)
.addStatement("$1L = $1L.setUdtValue($2L, $3L)", targetName, cqlName, udtValueName);
if (useNullSavingStrategy) {
methodBuilder.nextControlFlow(
"else if ($L == $T.$L)",
NULL_SAVING_STRATEGY,
NullSavingStrategy.class,
NullSavingStrategy.SET_TO_NULL);
} else {
methodBuilder.nextControlFlow("else");
}
methodBuilder
.addStatement("$1L = $1L.setUdtValue($2L, null)", targetName, cqlName)
.endControlFlow();
} else {
// Collection of other entity class(es): the CQL column is a collection of mapped UDTs
// Build a copy of the value, encoding all entities into UdtValue instances on the fly.
String mappedCollectionName = enclosingClass.getNameIndex().uniqueField("mappedCollection");
String rawCollectionName = enclosingClass.getNameIndex().uniqueField("rawCollection");
methodBuilder
.addStatement("$T $L = $L", type.asTypeName(), mappedCollectionName, valueExtractor)
.beginControlFlow("if ($L != null)", mappedCollectionName);
CodeBlock currentCqlType = CodeBlock.of("$L.getType($L)", targetName, cqlName);
CodeBlock.Builder udtTypesBuilder = CodeBlock.builder();
CodeBlock.Builder conversionCodeBuilder = CodeBlock.builder();
convertEntitiesIntoUdts(
mappedCollectionName,
rawCollectionName,
type,
currentCqlType,
udtTypesBuilder,
conversionCodeBuilder,
enclosingClass,
useLeniency);
methodBuilder
.add(udtTypesBuilder.build())
.add(conversionCodeBuilder.build())
.addStatement(
"$1L = $1L.set($2L, $3L, $4L)",
targetName,
cqlName,
rawCollectionName,
enclosingClass.addGenericTypeConstant(type.asRawTypeName()));
if (useNullSavingStrategy) {
methodBuilder.nextControlFlow(
"else if ($L == $T.$L)",
NULL_SAVING_STRATEGY,
NullSavingStrategy.class,
NullSavingStrategy.SET_TO_NULL);
} else {
methodBuilder.nextControlFlow("else");
}
methodBuilder
.addStatement(
"$1L = $1L.set($2L, null, $3L)",
targetName,
cqlName,
enclosingClass.addGenericTypeConstant(type.asRawTypeName()))
.endControlFlow();
}
}