SimpleStreamReadContext.java
package tools.jackson.core.util;
import tools.jackson.core.*;
import tools.jackson.core.exc.StreamReadException;
import tools.jackson.core.io.ContentReference;
import tools.jackson.core.json.DupDetector;
/**
* Basic implementation of {@link TokenStreamContext} useful for most
* format backend {@link JsonParser} implementations
* (with notable exception of JSON that needs bit more advanced state).
*
* @since 3.0
*/
public class SimpleStreamReadContext extends TokenStreamContext
{
/**
* Parent context for this context; null for root context.
*/
protected final SimpleStreamReadContext _parent;
// // // Optional duplicate detection
protected DupDetector _dups;
/*
/**********************************************************************
/* Simple instance reuse slots; speed up things a bit (10-15%)
/* for docs with lots of small arrays/objects
/**********************************************************************
*/
protected SimpleStreamReadContext _childToRecycle;
/*
/**********************************************************************
/* Location/state information (minus source reference)
/**********************************************************************
*/
protected String _currentName;
protected Object _currentValue;
protected int _lineNr;
protected int _columnNr;
/*
/**********************************************************************
/* Instance construction, config, reuse
/**********************************************************************
*/
public SimpleStreamReadContext(int type, SimpleStreamReadContext parent, int nestingDepth,
DupDetector dups,
int lineNr, int colNr) {
super();
_parent = parent;
_nestingDepth = nestingDepth;
_dups = dups;
_type = type;
_lineNr = lineNr;
_columnNr = colNr;
_index = -1;
}
// REMOVE as soon as nothing uses this
@Deprecated
public SimpleStreamReadContext(int type, SimpleStreamReadContext parent,
DupDetector dups,
int lineNr, int colNr) {
super();
_parent = parent;
_dups = dups;
_type = type;
_lineNr = lineNr;
_columnNr = colNr;
_index = -1;
_nestingDepth = -1;
}
protected void reset(int type, int lineNr, int colNr) {
_type = type;
_currentValue = null;
_lineNr = lineNr;
_columnNr = colNr;
_index = -1;
_currentName = null;
if (_dups != null) {
_dups.reset();
}
}
@Override
public Object currentValue() {
return _currentValue;
}
@Override
public void assignCurrentValue(Object v) {
_currentValue = v;
}
/*
/**********************************************************************
/* Factory methods
/**********************************************************************
*/
public static SimpleStreamReadContext createRootContext(int lineNr, int colNr, DupDetector dups) {
return new SimpleStreamReadContext(TYPE_ROOT, null, 0, dups, lineNr, colNr);
}
public static SimpleStreamReadContext createRootContext(DupDetector dups) {
return createRootContext(1, 0, dups);
}
public SimpleStreamReadContext createChildArrayContext(int lineNr, int colNr) {
SimpleStreamReadContext ctxt = _childToRecycle;
if (ctxt == null) {
_childToRecycle = ctxt = new SimpleStreamReadContext(TYPE_ARRAY, this,
_nestingDepth + 1,
(_dups == null) ? null : _dups.child(), lineNr, colNr);
} else {
ctxt.reset(TYPE_ARRAY, lineNr, colNr);
}
return ctxt;
}
public SimpleStreamReadContext createChildObjectContext(int lineNr, int colNr) {
SimpleStreamReadContext ctxt = _childToRecycle;
if (ctxt == null) {
_childToRecycle = ctxt = new SimpleStreamReadContext(TYPE_OBJECT, this,
_nestingDepth + 1,
(_dups == null) ? null : _dups.child(), lineNr, colNr);
return ctxt;
}
ctxt.reset(TYPE_OBJECT, lineNr, colNr);
return ctxt;
}
/*
/**********************************************************************
/* Abstract method implementations, overrides
/**********************************************************************
*/
/**
* @since 3.0
*/
@Override public String currentName() { return _currentName; }
@Override public boolean hasCurrentName() { return _currentName != null; }
@Override public SimpleStreamReadContext getParent() { return _parent; }
@Override
public TokenStreamLocation startLocation(ContentReference srcRef) {
// We don't keep track of offsets at this level (only reader does)
long totalChars = -1L;
return new TokenStreamLocation(srcRef,
totalChars, _lineNr, _columnNr);
}
/*
/**********************************************************************
/* Extended API
/**********************************************************************
*/
/**
* Method that can be used to both clear the accumulated references
* (specifically value set with {@link #assignCurrentValue(Object)})
* that should not be retained, and returns parent (as would
* {@link #getParent()} do). Typically called when closing the active
* context when encountering {@link JsonToken#END_ARRAY} or
* {@link JsonToken#END_OBJECT}.
*
* @return Parent context of this context node, if any; {@code null} for root context
*/
public SimpleStreamReadContext clearAndGetParent() {
_currentValue = null;
// could also clear the current name, but seems cheap enough to leave?
return _parent;
}
public DupDetector getDupDetector() {
return _dups;
}
/*
/**********************************************************************
/* State changes
/**********************************************************************
*/
/**
* Method to call to advance index within current context: to be called
* when a new token found within current context (property name for objects,
* value for root and array contexts)
*
* @return Index after increment
*/
public int valueRead() {
return ++_index; // starts from -1
}
/**
* Method called to indicate what the "current" name (Object property name
* just decoded) is: may also trigger duplicate detection.
*
* @param name Name of Object property encountered
*
* @throws StreamReadException If there is a duplicate name violation
*/
public void setCurrentName(String name)
throws StreamReadException
{
_currentName = name;
if (_dups != null) { _checkDup(_dups, name); }
}
protected void _checkDup(DupDetector dd, String name)
throws StreamReadException
{
if (dd.isDup(name)) {
Object src = dd.getSource();
throw new StreamReadException(((src instanceof JsonParser) ? ((JsonParser) src) : null),
"Duplicate Object property \""+name+"\"");
}
}
}