edu.byu.hbll.json.JsonField Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of json Show documentation
Show all versions of json Show documentation
Various JSON helper classes and utilities based on Jackson. This also provides as compile dependencies the Jackson annotations, core, databind, datatype-jdk8, module-jaxb-annotations, and datatype-jsr310 modules along with snakeyaml. Therefore you only need to declare this library as a dependency in order to include those other dependencies.
package edu.byu.hbll.json;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.MissingNode;
import com.fasterxml.jackson.databind.node.NullNode;
/**
* A convenience class for working with {@link JsonNode}s. The {@link JsonNode} is very powerful;
* however, many common operations are difficult to execute. This fixes many of the problems by
* wrapping a {@link JsonNode} node and exposing the operations through a simpler API. This also
* holds the key or field name of a {@link JsonNode} when appropriate and not just the value.
*/
public class JsonField implements Iterable {
private String key;
private JsonNode value;
/** @param value the json node value */
public JsonField(JsonNode value) {
this("0", value);
}
/**
* @param key the key or field name
* @param value the json node value
*/
public JsonField(String key, JsonNode value) {
this.key = Objects.requireNonNull(key);
this.value = Objects.requireNonNull(value);
}
/**
* Same as {@link JsonNode#fieldNames()} with the following exceptions.
*
*
* - The field names are returned in a list rather than an iterator.
*
- This works for arrays and value nodes as well. For arrays, the field name is the index of
* the element. For value nodes, the field name is always "0".
*
*
* @return the child field names for objects, the element indexes for arrays, and "0" for value
* nodes
*/
public List fieldNames() {
List fieldNames = this.stream().map(JsonField::getKey).collect(Collectors.toList());
return fieldNames;
}
/**
* Same as {@link JsonNode#fields()} with the following exceptions.
*
*
* - The fields are returned in a list of {@link JsonField}s rather than an iterator of {@link
* JsonNode}s.
*
- The fields contain the key as well as the value.
*
- This works for arrays and value nodes as well. For arrays, the key is the index of the
* element. For value nodes, the key is always "0" and the value is the node itself. {@link
* MissingNode}s and {@link NullNode}s are not iterated.
*
*
* @return the child fields for objects, the elements for arrays, the node itself for value nodes
*/
public List fields() {
List nodes = new ArrayList<>();
if (value.isObject()) {
// if object return child fields
Iterator> fields = value.fields();
while (fields.hasNext()) {
Map.Entry field = fields.next();
nodes.add(new JsonField(field.getKey(), field.getValue()));
}
} else if (value.isArray()) {
// if array return elements with key being the index
int key = 0;
for (JsonNode value : value) {
nodes.add(new JsonField("" + (key++), value));
}
} else if (value.isMissingNode() || value.isNull()) {
// do nothing
} else {
// if value node return self
nodes.add(new JsonField("0", value));
}
return nodes;
}
/** @return the key or field name */
public String getKey() {
return key;
}
/** @return the json node value */
public JsonNode getValue() {
return value;
}
@Override
public String toString() {
return JsonNodeFactory.instance.textNode(key) + ":" + value;
}
@Override
public Iterator iterator() {
return fields().iterator();
}
public Stream stream() {
return fields().stream();
}
}