Validating properties are present with Boon
Pages (34)
- Auto Growable Byte Buffer like a ByteBuilder
- Background information on Boon datarepo
- BenchMarking
- Birth of Boon
- Boon Byte Builder Round 2 (read and write primitives to a byte array)
- Boon Data Repo Indexed Collections and ETL for Java Beans, JSON, Maps
- Boon DI
- Boon Filtering for Java beans, JSON and Maps
- Boon JSON
- Boon JSON in five minutes
- Boon path expressions
- Boon Slice Notation
- Boon Slice Notation for List, Set, Map, and primitive arrays
- Boon Sorting
- Boon String Slicing
- Show 19 more pages…
- Auto Growable Byte Buffer like a ByteBuilder
- Background information on Boon datarepo
- BenchMarking
- Birth of Boon
- Boon Byte Builder Round 2 (read and write primitives to a byte array)
- Boon Data Repo Indexed Collections and ETL for Java Beans, JSON, Maps
- Boon DI
- Boon Filtering for Java beans, JSON and Maps
- Boon JSON
- Boon JSON in five minutes
- Boon path expressions
- Boon Slice Notation
- Boon Slice Notation for List, Set, Map, and primitive arrays
- Boon Sorting
- Boon String Slicing
- Show 19 more pages…
Clone this wiki locally
Jackson has configuration in annotations for things like properties that are required. There is nothing wrong with this feature. I have used it myself. But Boon does not do this. Boon is more like MongoDB when it comes to property names/field names. It does not validate the existence of properties by design.
Repeat Boon does not validate existence of properties. Why? It does not want to. 1st reason Boon has a validation framework, and 2nd the standard Java validation framework exists. 3rd it is hard to have a generic way without a ton of complicated annotations to have validation per use case or view.
But Boon is a set of tools to expose meta-data from Java so you can roll your own framework.
Boon is not a framework. It is a lib. It does not prescribe one way to do things and try to fit every application into a mold. It makes things like querying meta data so you can build your own capabilities, and instead of bending your code to fit the framework, you just use the lib the way that you want.
Frameworks provide training wheels. Some people need training wheels. Some people like to build their own bike. Boon is for the latter.
Here is an example:
Jackson has configuration in annotations for things like properties that are required. There is nothing wrong with this feature. I have used it myself. But Boon does not do this. Boon is more like MongoDB when it comes to property names/field names. It does not validate the existence of properties by design.
Repeat Boon does not validate existence of properties. Why? It does not want to. 1st reason Boon has a validation framework, and 2nd the standard Java validation framework exists. 3rd it is hard to have a generic way without a ton of complicated annotations to have validation per use case or view.
But Boon is a set of tools to expose meta-data from Java so you can roll your own framework.
Boon is not a framework. It is a lib. It does not prescribe one way to do things and try to fit every application into a mold. It makes things like querying meta data so you can build your own capabilities, and instead of bending your code to fit the framework, you just use the lib the way that you want.
Frameworks provide training wheels. Some people need training wheels. Some people like to build their own bike. Boon is for the latter.
Here is an example:
Boilerplate Employee class
public static class Employee {
String firstName;
@Required
String lastName;
List<String> todo;
public Employee(String firstName, String lastName, List<String> todo) {
this.firstName = firstName;
this.lastName = lastName;
this.todo = todo;
}
@Override
public String toString() {
return "Employee{" +
"firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", todo=" + todo +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Employee)) return false;
Employee employee = (Employee) o;
if (firstName != null ? !firstName.equals(employee.firstName) : employee.firstName != null) return false;
if (lastName != null ? !lastName.equals(employee.lastName) : employee.lastName != null) return false;
if (todo != null ? !todo.equals(employee.todo) : employee.todo != null) return false;
return true;
}
@Override
public int hashCode() {
int result = firstName != null ? firstName.hashCode() : 0;
result = 31 * result + (lastName != null ? lastName.hashCode() : 0);
result = 31 * result + (todo != null ? todo.hashCode() : 0);
return result;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public List<String> getTodo() {
return todo;
}
public void setTodo(List<String> todo) {
this.todo = todo;
}
}
Let's say we wanted to validate that the following JSON parse had the key called todos.
Querying class meta-data
Map<String, Object> map = mapper.parseMap("{\"firstName\":\"Hovik\",\"lastName\":\"Gambino\"} ");
//Validate
boolean hasTodos = map.containsKey("todo");
if (hasTodos) {
puts ("It has todo");
} else {
puts ("No todos!!!!");
}
The map is an index overlay which means that it is not fully parsed, but only parses the keys that you query. This is optimized for injecting the map into a Java Object.
So when you are done, you can...
Employee hovik3WithNoTodos = fromMap(map, Employee.class);
It is flexible. You can bend it. Shape it. There is very little overhead from the above and parsing direct. You could even have complex logic that queries the JSON object and decided for example which message bus it should go to, or validation, or routing, or... whatever. JSON in Boon has a map as an intermediate form. Do stuff with it. Do your own framework stuff.
You can manipulate the map before it gets injected too:
map.put("todo", list("Read Scala Book", "Learn Boon", "Learn Vertx and Groovy",
"Buy Rick Lunch", "Buy Rick Beer"));
Now let's say that you wanted to validate all fields that had the annotation Required, well you could do this:
Iterator<FieldAccess> properties = ClassMeta.classMeta(Employee.class).properties();
map = mapper.parseMap("{\"firstName\":\"Hovik\",\"lastTAAName\":\"Gambino\"} ");
while (properties.hasNext()) {
FieldAccess property = properties.next();
puts (property.name());
if (property.requiresInjection()) {
if (map.get(property.name())==null){
die("Property was required", property.name());
}
}
}
The above would throw an error until we fixed lastTAAName to be lastName.
Boon also has an object criteria API so you could do validation as follows:
map = mapper.parseMap("{\"firstName\":\"Hovik\",\"lastName\":\"Gambino\", \"todo\":[\"Eat Salad\"]} ");
map.size();
if (matches(map,
notNull("firstName"),
notEmpty("firstName"),
contains("todo", "Eat Salad"))
) {
puts ("Hovik is cool");
} else {
puts ("Hovik eat some damn salad");
}
You don't have to use pre-caned annotations. You can define your own. Be your own boss.
/**
* @author Rick Hightower
*/
@Target( {ElementType.METHOD, ElementType.FIELD, ElementType.TYPE, ElementType.PARAMETER} )
@Retention( RetentionPolicy.RUNTIME )
public @interface UseCase1 {
}
...
public class Employee {
String firstName;
@UseCase1
String lastName;
...
ClassMeta<Employee> employeeClassMeta = ClassMeta.classMeta(Employee.class);
Iterator<FieldAccess> properties = employeeClassMeta.properties();
map = mapper.parseMap("{\"firstName\":\"Hovik\",\"lastName\":\"Gambino\"} ");
while (properties.hasNext()) {
FieldAccess property = properties.next();
puts (property.name());
if (property.hasAnnotation("UseCase1")) {
if (map.get(property.name())==null){
die("Property was required", property.name());
}
}
}
Build your own adventure with Boon.
public static class Employee {
String firstName;
@Required
String lastName;
List<String> todo;
public Employee(String firstName, String lastName, List<String> todo) {
this.firstName = firstName;
this.lastName = lastName;
this.todo = todo;
}
@Override
public String toString() {
return "Employee{" +
"firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", todo=" + todo +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Employee)) return false;
Employee employee = (Employee) o;
if (firstName != null ? !firstName.equals(employee.firstName) : employee.firstName != null) return false;
if (lastName != null ? !lastName.equals(employee.lastName) : employee.lastName != null) return false;
if (todo != null ? !todo.equals(employee.todo) : employee.todo != null) return false;
return true;
}
@Override
public int hashCode() {
int result = firstName != null ? firstName.hashCode() : 0;
result = 31 * result + (lastName != null ? lastName.hashCode() : 0);
result = 31 * result + (todo != null ? todo.hashCode() : 0);
return result;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public List<String> getTodo() {
return todo;
}
public void setTodo(List<String> todo) {
this.todo = todo;
}
}
Let's say we wanted to validate that the following JSON parse had the key called todos.
Querying class meta-data
Map<String, Object> map = mapper.parseMap("{\"firstName\":\"Hovik\",\"lastName\":\"Gambino\"} ");
//Validate
boolean hasTodos = map.containsKey("todo");
if (hasTodos) {
puts ("It has todo");
} else {
puts ("No todos!!!!");
}
The map is an index overlay which means that it is not fully parsed, but only parses the keys that you query. This is optimized for injecting the map into a Java Object.
So when you are done, you can...
Employee hovik3WithNoTodos = fromMap(map, Employee.class);
It is flexible. You can bend it. Shape it. There is very little overhead from the above and parsing direct. You could even have complex logic that queries the JSON object and decided for example which message bus it should go to, or validation, or routing, or... whatever. JSON in Boon has a map as an intermediate form. Do stuff with it. Do your own framework stuff.
You can manipulate the map before it gets injected too:
map.put("todo", list("Read Scala Book", "Learn Boon", "Learn Vertx and Groovy",
"Buy Rick Lunch", "Buy Rick Beer"));
Now let's say that you wanted to validate all fields that had the annotation Required, well you could do this:
Iterator<FieldAccess> properties = ClassMeta.classMeta(Employee.class).properties();
map = mapper.parseMap("{\"firstName\":\"Hovik\",\"lastTAAName\":\"Gambino\"} ");
while (properties.hasNext()) {
FieldAccess property = properties.next();
puts (property.name());
if (property.requiresInjection()) {
if (map.get(property.name())==null){
die("Property was required", property.name());
}
}
}
The above would throw an error until we fixed lastTAAName to be lastName.
Boon also has an object criteria API so you could do validation as follows:
map = mapper.parseMap("{\"firstName\":\"Hovik\",\"lastName\":\"Gambino\", \"todo\":[\"Eat Salad\"]} ");
map.size();
if (matches(map,
notNull("firstName"),
notEmpty("firstName"),
contains("todo", "Eat Salad"))
) {
puts ("Hovik is cool");
} else {
puts ("Hovik eat some damn salad");
}
You don't have to use pre-caned annotations. You can define your own. Be your own boss.
/**
* @author Rick Hightower
*/
@Target( {ElementType.METHOD, ElementType.FIELD, ElementType.TYPE, ElementType.PARAMETER} )
@Retention( RetentionPolicy.RUNTIME )
public @interface UseCase1 {
}
...
public class Employee {
String firstName;
@UseCase1
String lastName;
...
ClassMeta<Employee> employeeClassMeta = ClassMeta.classMeta(Employee.class);
Iterator<FieldAccess> properties = employeeClassMeta.properties();
map = mapper.parseMap("{\"firstName\":\"Hovik\",\"lastName\":\"Gambino\"} ");
while (properties.hasNext()) {
FieldAccess property = properties.next();
puts (property.name());
if (property.hasAnnotation("UseCase1")) {
if (map.get(property.name())==null){
die("Property was required", property.name());
}
}
}
Build your own adventure with Boon.
No comments:
Post a Comment