This module is used by Helidon to generate types with builders (Prototypes) to be used in API of modules from a blueprint interface.
There are two modules that are used:
helidon-builder-api- module required incompilescope, contains annotations and APIs needed to write blueprints, and to build the generated codehelidon-builder-processor- module to be placed on annotation processor path, generates the sources
There is one module useful for internal development
helidon-builder-tests-common-types(located undertests/common-types) that contains blueprints for the types we use inhelidon-common-types. As the common types module is used by the processor, we would end up with a cyclic dependency, so this allows us to generate the next iteration of common types (requires manual copying of the generated types)
Generate all required types for Helidon APIs with builders, that follow the same style (method names, required validation etc.).
The following list of features is currently supported:
Builderalso implements the interface of the type (all getters are available also on builder)Typeoptions - interface returnsType, such an option MUST NOT be null in the built instance, there is a validation in place on calling thebuildorbuildPrototypemethods. Getters MAY return null on a builderOptionaloptions - interface returnsOptional<Type>, setters use justType, there is a package local setter that acceptsOptionalas well, to support updating a builder from an existing instanceListoptions - interface returnsList<Type>, never null - if there is no configured value, empty string is returnedSetoptions - similar to listMapoptions - key/value map, builders support any key/value types, but if configuration is used, the key must be a string- "Singular" for collection based options, which adds setter for a single value (for
List<String> algorithms(), there would be the following setters:algorithms(List<String>),addAlgorithms(List<String>),addAlgorithm(String)) - A type can be
@Configured, which adds integration with Helidon common Config module, by adding a static factory methodcreate(io.helidon.common.Config)to the generated type, as well asconfig(Config)method to the generated builder, that sets all options annotated with@ConfiguredOptionfrom configuration (if present in the Config instance) - Capability to update the builder before validation (decorator)
- Support for custom methods (
@Prototype.CustomMethods) for factory methods, prototype methods, and builder methods
We are not building a general purpose solution, there are limitations that are known and will not be targetted:
- the solution expects that everything is single package - blueprints are required to be package local, which does not allow using built types across packages within a single module
- we only support interface based definition of blueprints (no classes)
- we only support non-nullable options, instead of nullable, use
Optionalgetters - implementation types of collections are fixed to
java.util.ArrayList,java.util.LinkedHashSetandjava.util.LinkedHashMap
- Write your interface that you want to have a builder for.
interface MyConfigBeanBlueprint {
String getName();
boolean isEnabled();
int getPort();
}- Annotate your interface definition with
@Blueprint, and optionally use@ConfiguredOption,Singularetc. to customize the getter methods. Remember to review the annotation attributes javadoc for any customizations. - Update your pom file to add annotation processor
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>io.helidon.builder</groupId>
<artifactId>helidon-builder-processor</artifactId>
<version>${helidon.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
<!--
the following section is to enable correct reactor ordering without adding processor
to module classpath/module path
this is ONLY needed when adding (any) Helidon processor to a Helidon module (within the same Maven project)
-->
<dependencies>
<dependency>
<groupId>io.helidon.builder</groupId>
<artifactId>helidon-builder-processor</artifactId>
<version>${helidon.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
...Generated types will be available under ./target/generated-sources/annotations
- MyConfigBean (in the same package as MyConfigBeanBlueprint), with inner classes
BuilderBase(for inheritance),Builder, - Support for
toString(),hashCode(), andequals()are always included. - Support for
builder(MyConfigBean)to create a new builder from an existing instance - Support for
from(MyConfigBean)andfrom(MyConfigBean.BuilderBase<?, ?>)to update builder from an instance or builder - Support for validation of required and non-nullable options (required options are options that have
@ConfiguredOption(required=true), non-nullable option is any option that is not primitive, collection, and does not return anOptional) - Support for builder decorator (
@Bluprint(decorator = MyDecorator.class)),class MyDecorator implements BuilderDecorator