Creates Java objects from strings without using reflection or annotations. Used by Gumdrop-Json and HttpFormReader.
The Builder class is very simple: it binds strings to setters and uses those bindings to populate instances.
Consider a Name
class:
import java.util.Objects;
public class Name {
private String first, last;
public Name() {
}
public Name(String first, String last) {
this.first = first;
this.last = last;
}
public String getFirst() {
return first;
}
public void setFirst(String first) {
this.first = first;
}
public String getLast() {
return last;
}
public void setLast(String last) {
this.last = last;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Name name = (Name) o;
return Objects.equals(first, name.first) &&
Objects.equals(last, name.last);
}
}
Let's create a Builder
for our Name
class:
Builder<Name> nameBuilder = new Builder<>(Name::new);
nameBuilder.addSetter("first", Name::setFirst);
What we've done is bind the string "first" to the setter setFirst
. Having done that, we can now send strings into our
Builder
object and have them be applied to our Name
instance:
Name name = nameBuilder.construct();
nameBuilder.apply(name, "first", "Bilbo");
assertEquals("Bilbo", name.getFirst());
This simple concept is the foundation for how Gumdrop populates Java obects from JSON, from URL parameters, and from
form submissions. The idea is that we wire up the relationships using a simple API, giving us compile-time type
safety (and as a side-benefit, excellent performance), and Builder
creates and populates objects from string values.
When building objects (for example from JSON), we often don't just build simple objects, but rather trees or graphs of nested objects. To handle object graphs, Gumdrop provides BuilderNode.
Let's look at an example where we populate a List
of Name
objects:
Builder<Name> nameBuilder = new Builder<>(Name::new);
nameBuilder.addSetter("first", Name::setFirst);
nameBuilder.addSetter("last", Name::setLast);
Builder<List<Name>> listBuilder = new Builder<>(ArrayList::new);
listBuilder.addMember("name", List::add, nameBuilder);
BuilderNode<List<Name>> listNode = new BuilderNode<>(listBuilder);
BuilderNode<?> nameNode1 = listNode.create("name");
nameNode1.applyString("first", "foo");
nameNode1.applyString("last", "bar");
BuilderNode<?> nameNode2 = listNode.create("name");
nameNode2.applyString("first", "baz");
nameNode2.applyString("last", "glarch");
List<Name> list = listNode.getObject();
assertEquals(List.of(new Name("foo", "bar"), new Name("baz", "glarch")), list);
Here, BuilderNode
s construct and wrap any member objects. When we call create
on a BuilderNode
the member object
is created and wrapped, and the corresponding sub-BuilderNode
is returned.
This example should provide a basic idea of how Gumdrop handles JSON deserialization as well as how it builds objects from form submissions.
For more examples, see BuilderTests and others.
Basic HTTP classes.
Simple validation facilities used throughout Gumdrop.