diff --git a/record-builder-processor/src/main/java/io/soabase/recordbuilder/processor/InternalRecordBuilderProcessor.java b/record-builder-processor/src/main/java/io/soabase/recordbuilder/processor/InternalRecordBuilderProcessor.java index 54aa985..84102fd 100644 --- a/record-builder-processor/src/main/java/io/soabase/recordbuilder/processor/InternalRecordBuilderProcessor.java +++ b/record-builder-processor/src/main/java/io/soabase/recordbuilder/processor/InternalRecordBuilderProcessor.java @@ -15,8 +15,13 @@ */ package io.soabase.recordbuilder.processor; -import com.squareup.javapoet.*; -import io.soabase.recordbuilder.core.RecordBuilder; +import static io.soabase.recordbuilder.processor.CollectionBuilderUtils.SingleItemsMetaDataMode.EXCLUDE_WILDCARD_TYPES; +import static io.soabase.recordbuilder.processor.CollectionBuilderUtils.SingleItemsMetaDataMode.STANDARD; +import static io.soabase.recordbuilder.processor.CollectionBuilderUtils.SingleItemsMetaDataMode.STANDARD_FOR_SETTER; +import static io.soabase.recordbuilder.processor.ElementUtils.getBuilderName; +import static io.soabase.recordbuilder.processor.ElementUtils.getWithMethodName; +import static io.soabase.recordbuilder.processor.RecordBuilderProcessor.generatedRecordBuilderAnnotation; +import static io.soabase.recordbuilder.processor.RecordBuilderProcessor.recordBuilderGeneratedAnnotation; import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.*; @@ -29,11 +34,8 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; -import static io.soabase.recordbuilder.processor.CollectionBuilderUtils.SingleItemsMetaDataMode.*; -import static io.soabase.recordbuilder.processor.ElementUtils.getBuilderName; -import static io.soabase.recordbuilder.processor.ElementUtils.getWithMethodName; -import static io.soabase.recordbuilder.processor.RecordBuilderProcessor.generatedRecordBuilderAnnotation; -import static io.soabase.recordbuilder.processor.RecordBuilderProcessor.recordBuilderGeneratedAnnotation; +import com.squareup.javapoet.*; +import io.soabase.recordbuilder.core.RecordBuilder; class InternalRecordBuilderProcessor { private final RecordBuilder.Options metaData; @@ -993,12 +995,21 @@ class InternalRecordBuilderProcessor { var parameterSpecBuilder = ParameterSpec.builder(type.valueType(), component.name()); methodSpec.addJavadoc("Set a new value for the {@code $L} record component in the builder\n", component.name()) - .addStatement("this.$L = $T.of($L)", component.name(), type.typeName(), component.name()); + .addStatement(getOptionalStatement(type), component.name(), type.typeName(), component.name()); addConstructorAnnotations(component, parameterSpecBuilder); methodSpec.addStatement("return this").addParameter(parameterSpecBuilder.build()); builder.addMethod(methodSpec.build()); } + private String getOptionalStatement(OptionalType type) { + + if(type.isOptional()) { + return "this.$L = $T.ofNullable($L)"; + } + + return "this.$L = $T.of($L)"; + } + private List typeVariablesWithReturn() { var variables = new ArrayList(); variables.add(rType); diff --git a/record-builder-processor/src/main/java/io/soabase/recordbuilder/processor/OptionalType.java b/record-builder-processor/src/main/java/io/soabase/recordbuilder/processor/OptionalType.java index 30ff138..c9917da 100644 --- a/record-builder-processor/src/main/java/io/soabase/recordbuilder/processor/OptionalType.java +++ b/record-builder-processor/src/main/java/io/soabase/recordbuilder/processor/OptionalType.java @@ -19,6 +19,7 @@ import java.util.Optional; import java.util.OptionalDouble; import java.util.OptionalInt; import java.util.OptionalLong; + import com.squareup.javapoet.ParameterizedTypeName; import com.squareup.javapoet.TypeName; @@ -58,4 +59,8 @@ public record OptionalType(TypeName typeName, TypeName valueType) { } return Optional.empty(); } + + public boolean isOptional() { + return typeName.equals(optionalType); + } } diff --git a/record-builder-test/src/main/java/io/soabase/recordbuilder/test/RecordWithOptional.java b/record-builder-test/src/main/java/io/soabase/recordbuilder/test/RecordWithOptional.java index 4191867..693bae5 100644 --- a/record-builder-test/src/main/java/io/soabase/recordbuilder/test/RecordWithOptional.java +++ b/record-builder-test/src/main/java/io/soabase/recordbuilder/test/RecordWithOptional.java @@ -15,6 +15,8 @@ */ package io.soabase.recordbuilder.test; +import javax.validation.constraints.NotNull; + import io.soabase.recordbuilder.core.RecordBuilder; import java.util.Optional; @@ -24,4 +26,4 @@ import java.util.OptionalLong; @RecordBuilder.Options(emptyDefaultForOptional = true, addConcreteSettersForOptional = true) @RecordBuilder -public record RecordWithOptional(Optional value, Optional raw, OptionalInt i, OptionalLong l, OptionalDouble d) {} +public record RecordWithOptional(@NotNull Optional value, Optional raw, OptionalInt i, OptionalLong l, OptionalDouble d) {} diff --git a/record-builder-test/src/test/java/io/soabase/recordbuilder/test/TestOptional.java b/record-builder-test/src/test/java/io/soabase/recordbuilder/test/TestOptional.java index 7e2bc37..e3c2eea 100644 --- a/record-builder-test/src/test/java/io/soabase/recordbuilder/test/TestOptional.java +++ b/record-builder-test/src/test/java/io/soabase/recordbuilder/test/TestOptional.java @@ -15,14 +15,14 @@ */ package io.soabase.recordbuilder.test; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - import java.util.Optional; import java.util.OptionalDouble; import java.util.OptionalInt; import java.util.OptionalLong; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + class TestOptional { @Test void testDefaultEmpty() { @@ -65,4 +65,19 @@ class TestOptional { Assertions.assertEquals(OptionalLong.of(424242L), record.l()); Assertions.assertEquals(OptionalDouble.of(42.42), record.d()); } + + @Test + void shouldAcceptNullForOptionalRawSetter() { + // given + String value = null; + + // when + var record = RecordWithOptionalBuilder.builder() + .value(value) + .build(); + + // then + Assertions.assertEquals(Optional.empty(), record.value()); + } + }