Top Description Inners Fields Constructors Methods
groovy.transform.builder

public Class InitializerStrategy

extends AbstractBuilderStrategy
Class Inheritance
Imports
groovy.transform.TupleConstructor, .Undefined, org.apache.groovy.ast.tools.AnnotatedNodeUtils, org.codehaus.groovy.ast.AnnotatedNode, .AnnotationNode, .ClassHelper, .ClassNode, .ConstructorNode, .FieldNode, .GenericsType, .InnerClassNode, .MethodNode, .Parameter, org.codehaus.groovy.ast.expr.Expression, org.codehaus.groovy.ast.stmt.BlockStatement, org.codehaus.groovy.ast.tools.GeneralUtils, org.codehaus.groovy.transform.AbstractASTTransformation, .BuilderASTTransformation, java.util.ArrayList, .List, .Map

This strategy is used with the Builder AST transform to create a builder helper class for the fluent and type-safe creation of instances of a specified class. It is modelled roughly on the design outlined here: http://michid.wordpress.com/2008/08/13/type-safe-builder-pattern-in-java/ You define classes which use the type-safe initializer pattern as follows:
import groovy.transform.builder.*
import groovy.transform.*

@ToString
@Builder(builderStrategy=InitializerStrategy) class Person {
    String firstName
    String lastName
    int age
}
While it isn't required to do so, the benefit of this builder strategy comes in conjunction with static type-checking or static compilation. Typical usage is as follows:
@CompileStatic
def main() {
    println new Person(Person.createInitializer().firstName("John").lastName("Smith").age(21))
}
which prints:
Person(John, Smith, 21)
If you don't initialise some of the properties, your code won't compile, e.g. if the method body above was changed to this:
println new Person(Person.createInitializer().firstName("John").lastName("Smith"))
then the following compile-time error would result:
[Static type checking] - Cannot find matching method Person#<init>(Person$PersonInitializer <groovy.transform.builder.InitializerStrategy$SET, groovy.transform.builder.InitializerStrategy$SET, groovy.transform.builder.InitializerStrategy$UNSET>). Please check if the declared type is correct and if the method exists.

The message is a little cryptic, but it is basically the static compiler telling us that the third parameter, age in our case, is unset. You can also add this annotation to your predefined constructors. These will be made private and an initializer will be set up to call your constructor. Any parameters to your constructor become the properties expected by the initializer. If you use such a builder on a constructor as well as on the class or on more than one constructor, then it is up to you to define unique values for 'builderClassName' and 'builderMethodName' for each annotation.

Nested and Inner Type Summary

Modifier and TypeClass and Description
public abstract static class
InitializerStrategy.SET

Internal phantom type used by the InitializerStrategy to indicate that a property has been set.

public abstract static class
InitializerStrategy.UNSET

Internal phantom type used by the InitializerStrategy to indicate that a property remains unset.

Field Summary

Modifier and TypeField and Description
private static final Expression
private static final ClassNode

Constructor Summary

AccessConstructor and Description
public

Method Summary

Modifier and TypeMethod and Description
private static void
addFields(ClassNode buildee, List<FieldNode> filteredFields, ClassNode builder)

public void
private void
buildCommon(ClassNode buildee, AnnotationNode anno, List<FieldNode> fieldNodes, ClassNode builder)

private static List<FieldNode>
convertParamsToFields(ClassNode builder, Parameter[] parameters)

private static void
createBuildeeConstructors(BuilderASTTransformation transform, ClassNode buildee, ClassNode builder, List<FieldNode> fields, boolean needsConstructor, boolean useSetters)

private static void
private static void
private void
createBuilderForAnnotatedClass(BuilderASTTransformation transform, ClassNode buildee, AnnotationNode anno, boolean useSetters, boolean allNames, boolean force)

private void
private static MethodNode
createBuilderMethod(String buildMethodName, ClassNode builder, int numFields, String builderMethodName)

private MethodNode
createBuilderMethodForField(ClassNode builder, List<FieldNode> fields, String prefix, int fieldPos)

private static MethodNode
createBuildMethod(ClassNode builder, String buildMethodName, List<FieldNode> fields)

private static FieldNode
private static ConstructorNode
private static ClassNode
createInnerHelperClass(ClassNode buildee, String builderClassName, int fieldsSize)

private static List<FieldNode>
filterFields(List<FieldNode> fieldNodes, List<String> includes, List<String> excludes, boolean allNames)

private static String
private static Parameter[]
private static void
initializeFields(List<FieldNode> fields, BlockStatement body, boolean useSetters)

private static GenericsType
private static void
renameMethod(ClassNode buildee, MethodNode mNode, String newName)

private static GenericsType[]
setGenTypes(int numFields)

private static GenericsType[]
unsetGenTypes(int numFields)

Inherited from org.codehaus.groovy.transform.BuilderASTTransformation.AbstractBuilderStrategy:
checkKnownFieldcheckKnownPropertygetFieldsgetIncludeExcludegetPropertyInfoFromBeanInfogetPropertyInfoFromClassNodegetPropertyInfoFromClassNodegetPropertyInfoFromClassNodegetPropertyInfosgetSetterNameunsupportedAttributeunsupportedAttribute

Field Detail

DEFAULT_INITIAL_VALUEback to summary
private static final Expression DEFAULT_INITIAL_VALUE
TUPLECONS_TYPEback to summary
private static final ClassNode TUPLECONS_TYPE

Constructor Detail

InitializerStrategyback to summary
public InitializerStrategy()

Method Detail

addFieldsback to summary
private static void addFields(ClassNode buildee, List<FieldNode> filteredFields, ClassNode builder)
buildback to summary
public void build(BuilderASTTransformation transform, AnnotatedNode annotatedNode, AnnotationNode anno)

Implements org.codehaus.groovy.transform.BuilderASTTransformation.BuilderStrategy.build.

buildCommonback to summary
private void buildCommon(ClassNode buildee, AnnotationNode anno, List<FieldNode> fieldNodes, ClassNode builder)
convertParamsToFieldsback to summary
private static List<FieldNode> convertParamsToFields(ClassNode builder, Parameter[] parameters)
createBuildeeConstructorsback to summary
private static void createBuildeeConstructors(BuilderASTTransformation transform, ClassNode buildee, ClassNode builder, List<FieldNode> fields, boolean needsConstructor, boolean useSetters)
createBuildeeMethodsback to summary
private static void createBuildeeMethods(ClassNode buildee, MethodNode mNode, ClassNode builder, List<FieldNode> fields)
createBuilderConstructorsback to summary
private static void createBuilderConstructors(ClassNode builder, ClassNode buildee, List<FieldNode> fields)
createBuilderForAnnotatedClassback to summary
private void createBuilderForAnnotatedClass(BuilderASTTransformation transform, ClassNode buildee, AnnotationNode anno, boolean useSetters, boolean allNames, boolean force)
createBuilderForAnnotatedMethodback to summary
private void createBuilderForAnnotatedMethod(BuilderASTTransformation transform, MethodNode mNode, AnnotationNode anno, boolean useSetters)
createBuilderMethodback to summary
private static MethodNode createBuilderMethod(String buildMethodName, ClassNode builder, int numFields, String builderMethodName)
createBuilderMethodForFieldback to summary
private MethodNode createBuilderMethodForField(ClassNode builder, List<FieldNode> fields, String prefix, int fieldPos)
createBuildMethodback to summary
private static MethodNode createBuildMethod(ClassNode builder, String buildMethodName, List<FieldNode> fields)
createFieldCopyback to summary
private static FieldNode createFieldCopy(ClassNode buildee, FieldNode fNode)
createInitializerConstructorback to summary
private static ConstructorNode createInitializerConstructor(ClassNode buildee, ClassNode builder, List<FieldNode> fields)
createInnerHelperClassback to summary
private static ClassNode createInnerHelperClass(ClassNode buildee, String builderClassName, int fieldsSize)
filterFieldsback to summary
private static List<FieldNode> filterFields(List<FieldNode> fieldNodes, List<String> includes, List<String> excludes, boolean allNames)
getBuilderClassNameback to summary
private static String getBuilderClassName(ClassNode buildee, AnnotationNode anno)
getParamsback to summary
private static Parameter[] getParams(List<FieldNode> fields, ClassNode cNode)
initializeFieldsback to summary
private static void initializeFields(List<FieldNode> fields, BlockStatement body, boolean useSetters)
makePlaceholderback to summary
private static GenericsType makePlaceholder(int i)
renameMethodback to summary
private static void renameMethod(ClassNode buildee, MethodNode mNode, String newName)
setGenTypesback to summary
private static GenericsType[] setGenTypes(int numFields)
unsetGenTypesback to summary
private static GenericsType[] unsetGenTypes(int numFields)
groovy.transform.builder back to summary

public abstract Class InitializerStrategy.SET

extends Object
Class Inheritance

Internal phantom type used by the InitializerStrategy to indicate that a property has been set. It is used in conjunction with the generated parameterized type helper class.

Constructor Summary

AccessConstructor and Description
public
SET()

Method Summary

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Constructor Detail

SETback to summary
public SET()
groovy.transform.builder back to summary

public abstract Class InitializerStrategy.UNSET

extends Object
Class Inheritance

Internal phantom type used by the InitializerStrategy to indicate that a property remains unset. It is used in conjunction with the generated parameterized type helper class.

Constructor Summary

AccessConstructor and Description
public

Method Summary

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Constructor Detail

UNSETback to summary
public UNSET()