kuujo/vertigo — pull request #20 by kuujo (2013-11-16 08:13:27+00:00)
Title: Json schemas

This adds schema validation for component inputs with the following changes:
* a `declareSchema` method is added to `InputCollector`
* a `declareSchema` method is added to the base `Component` interface (through which it is added to the component's `InputCollector`)
* the `declareSchema` methods accept a `JsonSchema` instance
* each `JsonSchema` can create a `JsonValidator` instance, which can validate any `JsonElement` (`JsonObject` or `JsonArray`)
* the `ObjectSchema` and `ArraySchema` classes are the basic object and array schema implementations
* each field in `ObjectSchema` can define a data type and/or a schema (for cases where the required value is a `JsonObject` or `JsonArray`)
* the `ArraySchema` can define the data type or schema of its elements
* also adds `Field` and `Fields` classes which represent a field and a collection of fields respecively

Example:

`MathVerticle.java`

```java
vertigo.createBasicWorker().start(new Handler>() {
public void handle(AsyncResult result) {
if (result.failed()) {
return;
}

final BasicWorker worker = result.result();

// Create a schema that requires a message structure like:
// {
// "operator": "+",
// "values": [1, 2, 3]
"" }
ObjectSchema schema = new ObjectSchema();
schema.addField("operator", String.class);
schema.addField("values", new ArraySchema().setType(Integer.class));

// Add the schema to the worker.
worker.declareSchema(schema);

// Register a message handler that calculates a value.
worker.messageHandler(new Handler() {
public void handle(JsonMessage message) {
// We can be confident that the "operator" field exists and is a String.
String operator = message.body().getString("operator");
switch (operator) {
case "+":
int sum = 0;
// We can be confident that each of these values are integers.
for (Object num : message.body().getArray("values")) {
sum += Integer.valueOf(num);
}
worker.emit(new JsonObject().putString("sum", sum), message);
break;
case "*":
int product = 0;
// Again, we're still confident these are integers.
for (Object num : message.body().getArray("values")) {
product *= Integer.valueOf(num);
}
worker.emit(new JsonObject().putString("product", product), message);
break;
default:
worker.fail(message);
break;
}
}
});
}
});
```