From 3711b008158c88f382023b6f6f494bcc7bcda7e7 Mon Sep 17 00:00:00 2001 From: Jordan Zimmerman Date: Tue, 2 Jan 2024 14:24:58 +0000 Subject: [PATCH] Documentation for options Closes #162 --- README.md | 1 + customizing.md | 4 +-- options.md | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 options.md diff --git a/README.md b/README.md index ede5bf2f..b8a88f56 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ _Details:_ - [Generation Via Includes](#generation-via-includes) - [Usage](#usage) - [Customizing](customizing.md) (e.g. add immutable collections, etc.) +- [Options](options.md) ## RecordBuilder Example diff --git a/customizing.md b/customizing.md index dd0dae4d..91048753 100644 --- a/customizing.md +++ b/customizing.md @@ -9,7 +9,7 @@ enable optional features. # Customizing RecordBuilder RecordBuilder can be customized in a number of ways. The types of customizations will change over time. See -[@RecordBuilder.Options](record-builder-core/src/main/java/io/soabase/recordbuilder/core/RecordBuilder.java) +[RecordBuilder Options](options.md) for the current set of customizations and their default values. For example, the `useImmutableCollections` option adds special handling for record components of type `java.util.List`, `java.util.Set`, `java.util.Map` and `java.util.Collection`. When the record is built, any components of these types are passed through an added shim method that uses the corresponding immutable collection (e.g. `List.copyOf(o)`) or an empty immutable collection if the component is `null`. @@ -59,7 +59,7 @@ compilerArgs.addAll(['-AprefixEnclosingClassNames=false', '-AfileComment="someth ## Customize a single record -To customize a single record, add `@RecordBuilder.Options` in addition to +To customize a single record, add `@RecordBuilder.Options` ([options details](options.md)) in addition to `@RecordBuilder`. E.g. diff --git a/options.md b/options.md new file mode 100644 index 00000000..3ff5d443 --- /dev/null +++ b/options.md @@ -0,0 +1,97 @@ +[◀︎ RecordBuilder](README.md) • RecordBuilder Options + +# RecordBuilder Options + +RecordBuilder supports many options that change the behavior of generated builders. These options are added to over +time and the project is open to suggestions/submissions from users. + +Options are specified by adding `@RecordBuilder.Options` annotations on source records. The project's test +files have many examples. + +## Naming + +The names used for generated methods, classes, etc. can be changed via the following options: + +| option | details | +|-------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `@RecordBuilder.Options(suffix = "foo")` | The builder class name will be the name of the record (prefixed with any enclosing class) plus this suffix. | +| `@RecordBuilder.Options(interfaceSuffix = "Foo")` | Used by {@code RecordInterface}. The generated record will have the same name as the annotated interface plus this suffix. | +| `@RecordBuilder.Options(copyMethodName = "foo")` | The name to use for the copy builder. | +| `@RecordBuilder.Options(builderMethodName = "foo")` | The name to use for the builder. | +| `@RecordBuilder.Options(buildMethodName = "foo")` | The name to use for the build method. | +| `@RecordBuilder.Options(fromMethodName = "foo")` | The name to use for the from-to-wither method. | +| `@RecordBuilder.Options(componentsMethodName = "foo")` | The name to use for the method that returns the record components as a stream. | +| `@RecordBuilder.Options(withClassName = "Foo")` | The name to use for the nested With class. | +| `@RecordBuilder.Options(withClassMethodPrefix = "foo")` | The prefix to use for the methods in the With class. | +| `@RecordBuilder.Options(singleItemBuilderPrefix = "foo")` | The prefix for adder methods when `addSingleItemCollectionBuilders()` is enabled. | +| `@RecordBuilder.Options(fromWithClassName = "Foo")` | The `fromMethodName` method instantiates an internal private class. This is the name of that class. | +| `@RecordBuilder.Options(mutableListClassName = "Foo")` | If `addSingleItemCollectionBuilders()` and `useImmutableCollections()` are enabled the builder uses an internal class to track changes to lists. This is the name of that class. | +| `@RecordBuilder.Options(mutableSetClassName = "Foo")` | If `addSingleItemCollectionBuilders()` and `useImmutableCollections()` are enabled the builder uses an internal class to track changes to sets. This is the name of that class. | +| `@RecordBuilder.Options(mutableMapClassName = "Foo")` | If `addSingleItemCollectionBuilders()` and `useImmutableCollections()` are enabled the builder uses an internal class to track changes to maps. This is the name of that class. | +| `@RecordBuilder.Options(stagedBuilderMethodName = "foo")` | The name to use for the staged builder if present. | +| `@RecordBuilder.Options(stagedBuilderMethodSuffix = "Foo")` | The suffix to use for the staged builder interfaces if present. | +| `@RecordBuilder.Options(getterPrefix = "foo")` | If set, all builder getter methods will be prefixed with this string. | +| `@RecordBuilder.Options(booleanPrefix = "foo")` | If set, all boolean builder getter methods will be prefixed with this string. | + +## Withers + +| option | details | +|-------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------| +| `@RecordBuilder.Options(enableWither = true/false)` | The builder class name will be the name of the record (prefixed with any enclosing class) plus this suffix. The default is `true`. | +| `@RecordBuilder.Options(withClassName = "Foo")` | The name to use for the nested With class. | +| `@RecordBuilder.Options(withClassMethodPrefix = "foo")` | The prefix to use for the methods in the With class. | +| `@RecordBuilder.Options(addFunctionalMethodsToWith = true/false)` | When enabled, adds functional methods to the nested "With" class. The default is `false`. | +| `@RecordBuilder.Options(fromWithClassName = "Foo")` | The `fromMethodName` method instantiates an internal private class. This is the name of that class. | + +## File/Class Generation + +| option | details | +|------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------| +| `@RecordBuilder.Options(fileComment = "foo")` | Return the comment to place at the top of generated files. Return null or an empty string for no comment. | +| `@RecordBuilder.Options(fileIndent = " ")` | Return the file indent to use. | +| `@RecordBuilder.Options(prefixEnclosingClassNames = true/false)` | If the record is declared inside another class, the outer class's name will be prefixed to the builder name if this returns true. The default is `true`. | + +## Miscellaneous + +| option | details | +|----------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------| +| `@RecordBuilder.Options(inheritComponentAnnotations = true/false)` | If true, any annotations (if applicable) on record components are copied to the builder methods. The default is `true`. | +| `@RecordBuilder.Options(publicBuilderConstructors = true/false)` | Makes the generated builder's constructors public. The default is `false`. | +| `@RecordBuilder.Options(builderClassModifiers = {}})` | Any additional `javax.lang.model.element.Modifier` you wish to apply to the builder. | +| `@RecordBuilder.Options(beanClassName = "Foo")` | If set, the Builder will contain an internal interface with this name. | +| `@RecordBuilder.Options(addClassRetainedGenerated = true/false)` | If true, generated classes are annotated with `RecordBuilderGenerated`. The default is `false`. | +| `@RecordBuilder.Options(addStaticBuilder = true/false)` | If true, a functional-style builder is added so that record instances can be instantiated without `new()`. The default is `true`. | +| `@RecordBuilder.Options(inheritComponentAnnotations = true/false)` | If true, any annotations (if applicable) on record components are copied to the builder methods. The default is `true`. | +| `@RecordBuilder.Options(addConcreteSettersForOptional = true/false)` | Add non-optional setter methods for optional record components. The default is `false`. | +| `@RecordBuilder.Options(useValidationApi = true/false)` | Pass built records through the Java Validation API if it's available in the classpath. The default is `false`. | + +## Default Values / Initializers + +| option | details | +|--------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------| +| `@RecordBuilder.Options(emptyDefaultForOptional = true/false)` | Set the default value of `Optional` record components to `Optional.empty()`. The default is `true`. | + +### `@RecordBuilder.Initializer` + +You can annotate record components with `@RecordBuilder.Initializer(...)` to specify initializers for the corresponding +field in the generated builder. See [Initialized.java](record-builder-test/src/main/java/io/soabase/recordbuilder/test/Initialized.java) +for an example. + +## Null Handling + +| option | details | +|-----------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------| +| `@RecordBuilder.Options(interpretNotNulls = true/false)` | Add not-null checks for record components annotated with any null-pattern annotation. The default is `false`. | +| `@RecordBuilder.Options(interpretNotNullsPattern = "regex")` | The regex pattern used to determine if an annotation name means non-null. | +| `@RecordBuilder.Options(allowNullableCollections = true/false)` | Adds special null handling for record collectioncomponents. The default is `false`. | + +## Collections + +Special handling for collections. See the project test classes for usage. + +| option | details | +|------------------------------------------------------------------------|-------------------------------------------------------------------------------------| +| `@RecordBuilder.Options(useImmutableCollections = true/false)` | Adds special handling for collection record components. The default is `false`. | +| `@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`. |