Groovy AST transformations, such as @ValueObject and @NonNull, which makes constructing an instance more bullet-proof.
Groovy has the Immutable
annotation which allows to create immutable classes, which is a prerequisite for creating value objects. Unfortunately, when a class has been annotated with Immutable
it’s no longer possible to add your own constructor to verify if provided parameters are not null
, making our value objects really bullet-proof.
See Ted Vinke Blog: Make Your Groovy Objects More Bullet-Proof
Bulletproof helps to fill this gap by adding a few AST transformations.
NonNull
annotation which modifies every constructor to perform null-checks. Add this to an Immutable
class and no null
slips past your constructor.ValueObject
meta-annotation which puts both NonNull
and Immutable
on your class as a convenience to do above step with one annotation.Bulletproof requires Java 7 or later.
Add the bulletproof jar to the classpath in your preferred way and you’re set.
@Grab('com.github.tvinke:bulletproof:0.2')
compile group: 'com.github.tvinke', name: 'bulletproof', version: '0.2'
<dependency>
<groupId>com.github.tvinke</groupId>
<artifactId>bulletproof</artifactId>
<version>0.2</version>
</dependency>
Consult the bulletproof 0.2 Groovydocs for complete API information.
The NonNull
annotation on the class-level triggers an AST transformation which modifies every constructor to perform a null-check.
@groovy.transform.Immutable
@tvinke.bulletproof.transform.NonNull
class Person {
String name
}
new Person() // throws IllegalArgumentException: "Name can not be null"
The ValueObject
meta-annotation combines the Immutable
and NonNull
annotations, which is used to assist in the creation of value objects.
@tvinke.bulletproof.transform.ValueObject
class Money {
BigDecimal amount
}
new Money(amount: null) // throws IllegalArgumentException because of NonNull
def money = new Money(2.95)
money.amount = 3.0 // throws ReadOnlyPropertyException because of Immutable
TupleConstructor
) also to have null-checks performed. In this case probably also through the setters.