blob: 66520368ed1185cfd31412ce461ff0d1d676b931 [file] [log] [blame]
package com.fasterxml.jackson.databind.util;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.core.json.JsonReadContext;
/**
* Implementation of {@link JsonStreamContext} used by {@link TokenBuffer}
* to link back to the original context to try to keep location information
* consistent between source location and buffered content when it's re-read
* from the buffer.
*
* @since 2.9
*/
public class TokenBufferReadContext extends JsonStreamContext
{
protected final JsonStreamContext _parent;
protected final JsonLocation _startLocation;
// Benefit for reusing?
// protected JsonReadContext _child;
/*
/**********************************************************
/* Location/state information (minus source reference)
/**********************************************************
*/
protected String _currentName;
protected Object _currentValue;
protected TokenBufferReadContext(JsonStreamContext base, Object srcRef) {
super(base);
_parent = base.getParent();
_currentName = base.getCurrentName();
_currentValue = base.getCurrentValue();
if (base instanceof JsonReadContext) {
JsonReadContext rc = (JsonReadContext) base;
_startLocation = rc.getStartLocation(srcRef);
} else {
_startLocation = JsonLocation.NA;
}
}
protected TokenBufferReadContext(JsonStreamContext base, JsonLocation startLoc) {
super(base);
_parent = base.getParent();
_currentName = base.getCurrentName();
_currentValue = base.getCurrentValue();
_startLocation = startLoc;
}
/**
* Constructor for case where there is no real surrounding context: just create
* virtual ROOT
*/
protected TokenBufferReadContext() {
super(TYPE_ROOT, -1);
_parent = null;
_startLocation = JsonLocation.NA;
}
protected TokenBufferReadContext(TokenBufferReadContext parent, int type, int index) {
super(type, index);
_parent = parent;
_startLocation = parent._startLocation;
}
@Override
public Object getCurrentValue() {
return _currentValue;
}
@Override
public void setCurrentValue(Object v) {
_currentValue = v;
}
/*
/**********************************************************
/* Factory methods
/**********************************************************
*/
public static TokenBufferReadContext createRootContext(JsonStreamContext origContext) {
// First: possible to have no current context; if so, just create bogus ROOT context
if (origContext == null) {
return new TokenBufferReadContext();
}
return new TokenBufferReadContext(origContext, null);
}
public TokenBufferReadContext createChildArrayContext() {
return new TokenBufferReadContext(this, TYPE_ARRAY, -1);
}
public TokenBufferReadContext createChildObjectContext() {
return new TokenBufferReadContext(this, TYPE_OBJECT, -1);
}
/**
* Helper method we need to handle discontinuity between "real" contexts buffer
* creates, and ones from parent: problem being they are of different types.
*/
public TokenBufferReadContext parentOrCopy() {
// 30-Apr-2017, tatu: This is bit awkward since part on ancestor stack is of different
// type (usually `JsonReadContext`)... and so for unbalanced buffers (with extra
// END_OBJECT / END_ARRAY), we may need to create
if (_parent instanceof TokenBufferReadContext) {
return (TokenBufferReadContext) _parent;
}
if (_parent == null) { // unlikely, but just in case let's support
return new TokenBufferReadContext();
}
return new TokenBufferReadContext(_parent, _startLocation);
}
/*
/**********************************************************
/* Abstract method implementation
/**********************************************************
*/
@Override public String getCurrentName() { return _currentName; }
// @since 2.9
@Override public boolean hasCurrentName() { return _currentName != null; }
@Override public JsonStreamContext getParent() { return _parent; }
public void setCurrentName(String name) throws JsonProcessingException {
_currentName = name;
}
}