org.codehaus.jackson.node.NodeCursor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ehcache Show documentation
Show all versions of ehcache Show documentation
Ehcache is an open source, standards-based cache used to boost performance,
offload the database and simplify scalability. Ehcache is robust, proven and full-featured and
this has made it the most widely-used Java-based cache.
package org.codehaus.jackson.node;
import java.util.*;
import org.codehaus.jackson.*;
/**
* Helper class used by {@link TreeTraversingParser} to keep track
* of current location within traversed JSON tree.
*/
abstract class NodeCursor
extends JsonStreamContext
{
/**
* Parent cursor of this cursor, if any; null for root
* cursors.
*/
final NodeCursor _parent;
public NodeCursor(int contextType, NodeCursor p)
{
super();
_type = contextType;
_index = -1;
_parent = p;
}
/*
/**********************************************************
/* JsonStreamContext impl
/**********************************************************
*/
// note: co-variant return type
@Override
public final NodeCursor getParent() { return _parent; }
@Override
public abstract String getCurrentName();
/*
/**********************************************************
/* Extended API
/**********************************************************
*/
public abstract JsonToken nextToken();
public abstract JsonToken nextValue();
public abstract JsonToken endToken();
public abstract JsonNode currentNode();
public abstract boolean currentHasChildren();
/**
* Method called to create a new context for iterating all
* contents of the current structured value (JSON array or object)
*/
public final NodeCursor iterateChildren() {
JsonNode n = currentNode();
if (n == null) throw new IllegalStateException("No current node");
if (n.isArray()) { // false since we have already returned START_ARRAY
return new Array(n, this);
}
if (n.isObject()) {
return new Object(n, this);
}
throw new IllegalStateException("Current node of type "+n.getClass().getName());
}
/*
/**********************************************************
/* Concrete implementations
/**********************************************************
*/
/**
* Context matching root-level value nodes (i.e. anything other
* than JSON Object and Array).
* Note that context is NOT created for leaf values.
*/
protected final static class RootValue
extends NodeCursor
{
JsonNode _node;
protected boolean _done = false;
public RootValue(JsonNode n, NodeCursor p) {
super(JsonStreamContext.TYPE_ROOT, p);
_node = n;
}
@Override
public String getCurrentName() { return null; }
@Override
public JsonToken nextToken() {
if (!_done) {
_done = true;
return _node.asToken();
}
_node = null;
return null;
}
@Override
public JsonToken nextValue() { return nextToken(); }
@Override
public JsonToken endToken() { return null; }
@Override
public JsonNode currentNode() { return _node; }
@Override
public boolean currentHasChildren() { return false; }
}
/**
* Cursor used for traversing non-empty JSON Array nodes
*/
protected final static class Array
extends NodeCursor
{
Iterator _contents;
JsonNode _currentNode;
public Array(JsonNode n, NodeCursor p) {
super(JsonStreamContext.TYPE_ARRAY, p);
_contents = n.getElements();
}
@Override
public String getCurrentName() { return null; }
@Override
public JsonToken nextToken()
{
if (!_contents.hasNext()) {
_currentNode = null;
return null;
}
_currentNode = _contents.next();
return _currentNode.asToken();
}
@Override
public JsonToken nextValue() { return nextToken(); }
@Override
public JsonToken endToken() { return JsonToken.END_ARRAY; }
@Override
public JsonNode currentNode() { return _currentNode; }
@Override
public boolean currentHasChildren() {
// note: ONLY to be called for container nodes
return ((ContainerNode) currentNode()).size() > 0;
}
}
/**
* Cursor used for traversing non-empty JSON Object nodes
*/
protected final static class Object
extends NodeCursor
{
Iterator> _contents;
Map.Entry _current;
boolean _needEntry;
public Object(JsonNode n, NodeCursor p)
{
super(JsonStreamContext.TYPE_OBJECT, p);
_contents = ((ObjectNode) n).getFields();
_needEntry = true;
}
@Override
public String getCurrentName() {
return (_current == null) ? null : _current.getKey();
}
@Override
public JsonToken nextToken()
{
// Need a new entry?
if (_needEntry) {
if (!_contents.hasNext()) {
_current = null;
return null;
}
_needEntry = false;
_current = _contents.next();
return JsonToken.FIELD_NAME;
}
_needEntry = true;
return _current.getValue().asToken();
}
@Override
public JsonToken nextValue()
{
JsonToken t = nextToken();
if (t == JsonToken.FIELD_NAME) {
t = nextToken();
}
return t;
}
@Override
public JsonToken endToken() { return JsonToken.END_OBJECT; }
@Override
public JsonNode currentNode() {
return (_current == null) ? null : _current.getValue();
}
@Override
public boolean currentHasChildren() {
// note: ONLY to be called for container nodes
return ((ContainerNode) currentNode()).size() > 0;
}
}
}