- Notifications
You must be signed in to change notification settings - Fork0
Builder generator built on top of CodeAPI and Annotation Processing.
License
JonathanxD/BuilderGenerator
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Public version of CodeAPI BuilderGen.
BuilderGenerator generates the builder based on the source-code (CodeAPI BuilderGen generates builder based on class-file).
BuilderGenerator can only generate Java builders but supports all languages that generateJava Annotation Processing stubs
.
Classes generated by BuilderGenerator does not requires runtime-dependency
TODO
TODO
BuilderGenerator is designed to generate Builders for immutable objects, base classes must contains an inner classBuilder<T, B extends Builder<T, B>>
, also we recommend you to have aBuilder<BASE_CLASS, ?> builder()
method.
Base classes are classes that provide getter methods for properties. This class must provide aBuilder
class that standardize builder methods. Builder methods (with
methods) can also provide property options, see@PropertyInfo documentation orProperty specification section.
Example of valid base class:
interfacePerson {StringgetName();intgetAge();Builder<Person, ?>builder();interfaceBuilder<TextendsPerson,BextendsBuilder<T,B>>extendscom.myproject.BaseBuilder<T,B> {Builder<T,B>withName(Stringname);Builder<T,B>withAge(intage);// These methods are optional.StringgetName();StringgetAge(); }}
A baseBuilder
class is recommended to provide abuild()
method.
Note:BuilderGenerator provides aBuilder
class, but is not recommended to extend this class (to avoid runtime-dependency onBuilderGenerator).
Example ofBaseBuilder
:
interfaceBaseBuilder<T,BextendsBaseBuilder<T,B>> {Tbuild(); }
Implementation class is a concrete class that implements the base class.
Example:
classPersonImplimplementsPerson {privatefinalStringname;privatefinalintage;publicPersonImpl(Stringname,intage) {this.name =name;this.age =age; }@OverridepublicStringgetName() {returnthis.name; }@OverridepublicintgetAge() {returnthis.age; }@OverridepublicBuilder<Person, ?>builder() {thrownewUnsupportedOperationException(); }}
To generate Builder class you need to annotate the constructor of the implementation class OR annotate a static factory method.
Annotated constructor example:
classPersonImplimplementsPerson {privatefinalStringname;privatefinalintage;@GenBuilder(base =Person.class)publicPersonImpl(Stringname,intage) {this.name =name;this.age =age; }@OverridepublicStringgetName() {returnthis.name; }@OverridepublicintgetAge() {returnthis.age; }@OverridepublicBuilder<Person, ?>builder() {returnnewPersonBuilder(this); }}
Factory method example:
finalclassMyFactory {@GenBuilderpublicstaticPersonpersonFactory(Stringname,intage) {returnnewPersonImpl(name,age); }}
BytecodeGenerator provide a way to specify some property options like: value validator, default value provider and nullability.
To specify options for a property you need to annotate thebase builder property method.
Example:
interfacePerson {StringgetName();intgetAge();Builder<Person, ?>builder();interfaceBuilder<TextendsPerson,BextendsBuilder<T,B>>extendscom.myproject.BaseBuilder<T,B> {Builder<T,B>withName(Stringname);@PropertyInfo(validator =@Validator(@MethodRef(value =Validators.class,name ="positiveInt")))Builder<T,B>withAge(intage);// These methods are optional.StringgetName();StringgetAge(); }}
By default, properties value cannot be null.
BuilderGenerator supports Optional properties. Only properties where the getter method in the base class returns aOptional<T>
instance are marked asoptional property.
Example:
interfacePerson {StringgetName();intgetAge();Optional<LocalDate>getBirthDate();Builder<Person, ?>builder();interfaceBuilder<TextendsPerson,BextendsBuilder<T,B>>extendscom.myproject.BaseBuilder<T,B> {Builder<T,B>withName(Stringname);@PropertyInfo(validator =@Validator(@MethodRef(value =Validators.class,name ="positiveInt")))Builder<T,B>withAge(intage);// Make sure to accept non-Optional type. If you use Optional<LocalData> BuilderGenerator will not mark the property as 'optional property'.Builder<T,B>withBirthDate(LocalDatebirthDate);// These methods are optional.StringgetName();StringgetAge();Optional<LocalData>getBirthDate(); }}
- Method Reference Validation
Builder
inner class validation- Default value provider and validator inlining (read@Inline javadoc).
- BuilderGenerator does not require a base
Builder<T, B extends Builder<T, B>>
class, but it is recommended to provide abuild()
method. - BuilderGenerator automatically generate null checks for non-null
Object
properties
About
Builder generator built on top of CodeAPI and Annotation Processing.