com.bazaarvoice.jolt
public class Defaultr extends Object implements SpecDriven, Transform
{
"Rating":3,
"SecondaryRatings":{
"quality":{
"Range":7,
"Value":3,
"Id":"quality"
},
"sharpness": {
"Value":4,
"Id":"sharpness"
}
}
}
With the desired output being :
{
"Rating":3,
"RatingRange" : 5,
"SecondaryRatings":{
"quality":{
"Range":7,
"Value":3,
"Id":"quality",
"ValueLabel": null,
"Label": null,
"MaxLabel": "Great",
"MinLabel": "Terrible",
"DisplayType": "NORMAL"
},
"sharpness": {
"Range":5,
"Value":4,
"Id":"sharpness",
"ValueLabel": null,
"Label": null,
"MaxLabel": "High",
"MinLabel": "Low",
"DisplayType": "NORMAL"
}
}
}
This is what the Defaultr Spec would look like
{
"RatingRange" : 5,
"SecondaryRatings": {
"quality|value" : {
"ValueLabel": null,
"Label": null,
"MaxLabel": "Great",
"MinLabel": "Terrible",
"DisplayType": "NORMAL"
}
"*": {
"Range" : 5,
"ValueLabel": null,
"Label": null,
"MaxLabel": "High",
"MinLabel": "Low",
"DisplayType": "NORMAL"
}
}
}
The Spec file format for Defaulr a tree Map
{
"photos[]" : {
"2" : {
"url" : "http://www.bazaarvoice.com",
"caption" : ""
}
}
}
An Invalid Array Specification would be :
{
"photos[]" : {
"photo-id-1234" : {
"url" : "http://www.bazaarvoice.com",
"caption" : ""
}
}
}
Algorithm
Defaultr walks its Spec in a depth first way.
At each level in the Spec tree, Defaultr, works from most specific to least specific Spec key:
Literals key values
"|", sub-sorted by how many or values there, then alphabetically (for deterministic behavior)
"*"
At a given level in the Defaultr Spec tree, only literal keys force Defaultr to create new entries
in the input data: either as a single literal value or adding new nested Array or Map objects.
The wildcard operators, are applied after the literal keys, and will not cause the those keys to be
added if they are not already present in the input document (either naturally or having been defaulted
in from literal spec keys).
Algorithm :
1) Walk the spec
2) for each literal key in the spec (specKey)
2.1) if the the specKey is a map or array, and the input is null, default an empty Map or Array into the output
2.2.1) re-curse on the literal spec
2.2) if the the specKey is a map or array, and the input is not null, but of the "wrong" type, skip and do not recurse
2.2) if the the specKey, is a literal value, default the literal and value into the output and do not recurse
3) for each wildcard in the spec
3.1) find all keys from the defaultee that match the wildcard
3.2) treat each key as a literal speckey
Corner Cases :
Due to Defaultr's array syntax, we can't actually express that we expect the top level of the input to be an Array.
The workaround for this is that we check the type of the object that is at the root level of the input.
If it is a map, no problem.
If it is an array, we treat the "root" level of the Defaultr spec, as if it were the child of an Array type Defaultr entry.
To force unambiguity, Defaultr throws an Exception if the input is null.| Modifier and Type | Class and Description |
|---|---|
static interface |
Defaultr.WildCards |
@Inject public Defaultr(Object spec)
SpecException - for a malformed spec or if there are issuesCopyright © 2014. All Rights Reserved.