Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions options.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,8 @@ Special handling for collections. See the project test classes for usage.
| `@RecordBuilder.Options(useUnmodifiableCollections = true/false)` | Adds special handling for collection record components. The default is `false`. |
| `@RecordBuilder.Options(allowNullableCollections = true/false)` | Adds special null handling for record collectioncomponents. The default is `false`. |
| `@RecordBuilder.Options(addSingleItemCollectionBuilders = true/false)` | Adds special handling for record collectioncomponents. The default is `false`. |

## Required Components

You can annotate record components with `@RecordBuilder.Required` to generate a builder with required components in the builder parameters.
See [RequiredComponent.java](record-builder-test/src/main/java/io/soabase/recordbuilder/test/RequiredComponents.java) for an example.
Original file line number Diff line number Diff line change
Expand Up @@ -386,4 +386,13 @@ enum BuilderMode {
*/
Class<?> source() default Object.class;
}

/**
* Apply to record components to specify required components for the generated builder.
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.FIELD)
@Inherited
@interface Required {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,12 @@ class InternalRecordBuilderProcessor {
}
if ((metaData.builderMode() != BuilderMode.STAGED)
&& (metaData.builderMode() != BuilderMode.STAGED_REQUIRED_ONLY)) {
addStaticDefaultBuilderMethod();
if (record.getEnclosedElements().stream()
.anyMatch(element -> element.getAnnotation(RecordBuilder.Required.class) != null)) {
addStaticRequiredComponentsBuilderMethod(record);
} else {
addStaticDefaultBuilderMethod();
}
}
addStaticCopyBuilderMethod();
if (metaData.enableWither()) {
Expand Down Expand Up @@ -793,6 +798,29 @@ private void addStaticDefaultBuilderMethod() {
builder.addMethod(methodSpec);
}

private void addStaticRequiredComponentsBuilderMethod(TypeElement record) {
/*
* Adds the builder method with all required components similar to:
*
* public static MyRecordBuilder builder(int p1, int p2) { return new MyRecordBuilder().pi(pi).p2(p2); }
*/
var requiredParameters = record.getEnclosedElements().stream()
.filter(element -> element.getAnnotation(RecordBuilder.Required.class) != null)
.map(element -> ParameterSpec
.builder(TypeName.get(element.asType()), element.getSimpleName().toString()).build())
.toList();
var codeBuilder = CodeBlock.builder().add("return new $T()", builderClassType.typeName());
IntStream.range(0, requiredParameters.size()).forEach(index -> {
codeBuilder.add(".$L($L)", requiredParameters.get(index).name, requiredParameters.get(index).name);
});
var methodSpec = MethodSpec.methodBuilder(metaData.builderMethodName()).addParameters(requiredParameters)
.addJavadoc("Return a new builder with all fields set to the values taken from the given parameters\n")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC).addAnnotation(generatedRecordBuilderAnnotation)
.addTypeVariables(typeVariables).returns(builderClassType.typeName()).addStatement(codeBuilder.build())
.build();
builder.addMethod(methodSpec);
}

private void addStaticStagedBuilderMethod(String builderMethodName) {
/*
* Adds the staged builder method similar to:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright 2019 The original author or authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.soabase.recordbuilder.test;

import io.soabase.recordbuilder.core.RecordBuilder;

import java.util.Optional;

@RecordBuilder
public record RequiredComponents(@RecordBuilder.Required int a, @RecordBuilder.Required String b, float c,
Optional<Integer> d) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright 2019 The original author or authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.soabase.recordbuilder.test;

import org.junit.jupiter.api.Test;

import java.util.Optional;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class TestRequiredComponents {
@Test
void testRequiredComponents() {
var obj = RequiredComponentsBuilder.builder(100, "hello").build();
assertEquals(new RequiredComponents(100, "hello", 0.0f, Optional.empty()), obj);
}
}