This example models a builder-style API where methods must be called in a specific order to create a valid Email object.
import java.util.ArrayList;
import java.util.List;
import liquidjava.specification.*;
@StateSet({"empty", "senderSet", "receiverSet", "bodySet"})
public class Email {
@StateRefinement(to="empty()")
public Email() {}
@StateRefinement(from="empty()", to="senderSet()")
public Email from(String s) {}
@StateRefinement(from="senderSet() || receiverSet()", to="receiverSet()")
public Email to(String s) {}
@StateRefinement(from="receiverSet()")
public Email subject(String s) {}
@StateRefinement(from="receiverSet()", to="bodySet()")
public Email body(String s) {}
@StateRefinement(from="bodySet()")
public Email build() {}
}
Email email = new Email();
email.from("me")
.to("bob")
.to("alice")
.subject("greetings")
.body("hello!")
.build();
Email email = new Email();
email.from("me")
.to("bob")
.build(); // State Refinement Error
LiquidJava enforces the intended protocol:
- The
frommust be set first - The
tomust be set at least once before setting thebody - The
subjectis optional, but if used it must be set before thebody - The
buildmethod can only be called after the body is set