package com.fasterxml.jackson.jr.stree.util;
import java.util.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.jr.stree.JrsArray;
import com.fasterxml.jackson.jr.stree.JrsObject;
import com.fasterxml.jackson.jr.stree.JrsValue;
abstract class JrsValueCursor
extends JsonStreamContext
{
protected final JrsValueCursor _parent;
protected String _currentName;
protected java.lang.Object _currentValue;
public JrsValueCursor(int contextType, JrsValueCursor p)
{
super();
_type = contextType;
_index = -1;
_parent = p;
}
@Override
public final JrsValueCursor getParent() { return _parent; }
@Override
public final String getCurrentName() {
return _currentName;
}
public void overrideCurrentName(String name) {
_currentName = name;
}
@Override
public java.lang.Object getCurrentValue() {
return _currentValue;
}
@Override
public void setCurrentValue(java.lang.Object v) {
_currentValue = v;
}
public abstract JsonToken nextToken();
public abstract JsonToken nextValue();
public abstract JsonToken endToken();
public abstract JrsValue currentNode();
public abstract boolean currentHasChildren();
public final JrsValueCursor iterateChildren() {
JrsValue n = currentNode();
if (n == null) throw new IllegalStateException("No current node");
if (n.isArray()) {
return new ArrayCursor((JrsArray) n, this);
}
if (n.isObject()) {
return new ObjectCursor((JrsObject) n, this);
}
throw new IllegalStateException("Current node of type "+n.getClass().getName());
}
protected final static class RootCursor
extends JrsValueCursor
{
protected JrsValue _node;
protected boolean _done = false;
public RootCursor(JrsValue n, JrsValueCursor p) {
super(JsonStreamContext.TYPE_ROOT, p);
_node = n;
}
@Override
public void overrideCurrentName(String name) {
}
@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 JrsValue currentNode() { return _node; }
@Override
public boolean currentHasChildren() { return false; }
}
protected final static class ArrayCursor
extends JrsValueCursor
{
protected Iterator<JrsValue> _contents;
protected JrsValue _currentNode;
public ArrayCursor(JrsArray n, JrsValueCursor p) {
super(JsonStreamContext.TYPE_ARRAY, p);
_contents = n.elements();
}
@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 JrsValue currentNode() { return _currentNode; }
@Override
public boolean currentHasChildren() {
return currentNode().size() > 0;
}
}
protected final static class ObjectCursor
extends JrsValueCursor
{
protected Iterator<Map.Entry<String, JrsValue>> _contents;
protected Map.Entry<String, JrsValue> _current;
protected boolean _needEntry;
public ObjectCursor(JrsValue n, JrsValueCursor p)
{
super(JsonStreamContext.TYPE_OBJECT, p);
_contents = ((JrsObject) n).fields();
_needEntry = true;
}
@Override
public JsonToken nextToken()
{
if (_needEntry) {
if (!_contents.hasNext()) {
_currentName = null;
_current = null;
return null;
}
_needEntry = false;
_current = _contents.next();
_currentName = (_current == null) ? null : _current.getKey();
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 JrsValue currentNode() {
return (_current == null) ? null : _current.getValue();
}
@Override
public boolean currentHasChildren() {
return currentNode().size() > 0;
}
}
}