Java annotations and processor for creating fluent-api style POJO builders.
Java
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
buildable
example
.gitignore
README.md
build.gradle
gradle.properties
settings.gradle

README.md

Buildable

A java annotation processor for creating object builders with a fluent-interface.

  • Annotate classes with @Buildable
  • Annotate fields with @BuiltWith
  • Support for subclasses @BuildableSubclasses
  • Support for third party classes with @BuildableSpec, @InjectBuildable and @BuildField

Pre-requisites

  • Java 8, yup
  • Gradle (to build from source)

Releases via Maven Central

   <dependency>
    <groupId>com.bradneighbors.buildable</groupId>
    <artifactId>buildable</artifactId>
    <version>1.0.RELEASE</version>
   </dependency>

Modules

buildable

  • Contains the @Buildable, @BuildableSubclasses, and @BuiltWith annotations
  • Contains the @BuildableSpec, @InjectBuildable, and @BuildField annotations
  • Contains the Builder<T> interface that all builders will implement
  • Contains the annotation processors for creating Annotation Based Builders and Spec Based Builders.

example

  • Contains a few example classes with annotations
  • Contains a few example classes using @BuildableSpec
  • Contains unit tests that prove the annotation processor worked

Gradle

To build:

  gradle clean build

After building, look at example/generated/buildable/example/ to see what the generated builders look like. You can understand their API by looking at the tests in example/src/test/

Consuming in a Maven build

In your project's pom, you'll need something like this:

<dependencies>
    <dependency>
        <groupId>com.bradneighbors.buildable</groupId>
        <artifactId>buildable</artifactId>
        <version>1.0.RELEASE</version>
    </dependency>
</dependcies>
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.0</version>
            <configuration>
                <annotationProcessors>
                    <annotationProcessor>buildable.annotation.processor.BuildableCombinedProcessor</annotationProcessor>
                </annotationProcessors>
                <debug>true</debug>
                <optimize>true</optimize>
                <source>1.7</source>
                <target>1.7</target>
                <compilerArguments>
                <AaddGeneratedAnnotation>true</AaddGeneratedAnnotation>
                <Adebug>true</Adebug>
                </compilerArguments>
            </configuration>
        </plugin>
    </plugins>
</build>

Quick Example

For more examples, see the examples module.

To have a new builder generated for you given the following class:

import java.util.Date;

public class User {

  private String name;
  private String info;
  private Date birthDate;

  public User(String name, String info, Date birthDate) {
    this.name = name;
    this.info = info;
    this.birthDate = birthDate;
  }

Simply add the following annotations:

import java.util.Date;
import buildable.annotation.Buildable; // import this annotation
import buildable.annotation.BuiltWith; // import this annotation

@Buildable(name = "UserBuilder", factoryMethod = "aUser") 
public class User {

  @BuiltWith(methodName = "named", defaultValue = "Jane Doe")
  private String name;

  @BuiltWith
  private String info;

  @BuiltWith(methodName = "bornOn")
  private Date birthDate;

  private User(){}

  public User(String name, String info, Date birthDate) {
    this(); 
    this.name = name;
    this.info = info;
    this.birthDate = birthDate;
  }
}

This will generate a builder that looks something like this:

import buildable.Builder;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Date;

public class UserBuilder implements Builder<User> {

  public static UserBuilder aUser() {
    return new UserBuilder();
  }

  private UserBuilder() {}

  private java.lang.String name = "Jane Doe";
  public UserBuilder named(java.lang.String name) {
    this.name = name;
    return this;
  }


  private java.lang.String info = null;
  public UserBuilder withInfo(java.lang.String info) {
    this.info = info;
	return this;
  }
	
  private java.util.Date birthDate = null;
  public UserBuilder bornOn(java.util.Date birthDate) {
    this.birthDate = birthDate;
    return this;
  }

  public User build() {
	// commenting out for brevity here, just try for yourself and you'll see the fields getting set...
  }
}

To do the same using @BuildableSpec, create a new file to specify the configuration

import buildable.annotation.Buildable;
import buildable.annotation.BuiltWith;
import buildable.spec.BuildField;
import buildable.spec.BuildableSpec;
import buildable.spec.InjectBuildable;


@BuildableSpec
public class BuilderConfig {

    @InjectBuildable(value = @Buildable(factoryMethod = "aUser"),
            fields = {
                    @BuildField(name = "name", value =  @BuiltWith(methodName = "named", defaultValue = "\"Jane Doe\"") ),
                    @BuildField(name = "birthDate", value =   @BuiltWith(methodName = "bornOn")),
            }
    )
    private User user;
}

This will generate the exact same builder as the annotation based method.