package com.fasterxml.jackson.dataformat.smile;

import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.core.json.DupDetector;

Replacement for JsonWriteContext; while not strictly needed is more streamlined, optimal since there's no need to keep track of separators etc.
Since:2.10
/** * Replacement for {@code JsonWriteContext}; while not strictly * needed is more streamlined, optimal since there's no need to * keep track of separators etc. * * @since 2.10 */
public final class SmileWriteContext extends JsonStreamContext {
Parent context for this context; null for root context.
/** * Parent context for this context; null for root context. */
protected final SmileWriteContext _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 SmileWriteContext _childToRecycle; /* /********************************************************** /* Location/state information (minus source reference) /********************************************************** */
Name of the field of which value is to be written; only used for OBJECT contexts
/** * Name of the field of which value is to be written; only * used for OBJECT contexts */
protected String _currentName; protected Object _currentValue;
Marker used to indicate that we just wrote a field name (or Map name / id) and now expect a value to write
/** * Marker used to indicate that we just wrote a field name (or Map name / id) * and now expect a value to write */
protected boolean _gotFieldId; /* /********************************************************** /* Life-cycle /********************************************************** */ protected SmileWriteContext(int type, SmileWriteContext parent, DupDetector dups, Object currentValue) { super(); _type = type; _parent = parent; _dups = dups; _index = -1; _currentValue = currentValue; } private SmileWriteContext reset(int type, Object currentValue) { _type = type; _index = -1; // as long as _gotFieldId false, current name/id can be left as-is _gotFieldId = false; _currentValue = currentValue; if (_dups != null) { _dups.reset(); } return this; } public SmileWriteContext withDupDetector(DupDetector dups) { _dups = dups; return this; } @Override public Object getCurrentValue() { return _currentValue; } @Override public void setCurrentValue(Object v) { _currentValue = v; } /* /********************************************************** /* Factory methods /********************************************************** */ public static SmileWriteContext createRootContext(DupDetector dd) { return new SmileWriteContext(TYPE_ROOT, null, dd, null); } public SmileWriteContext createChildArrayContext(Object currentValue) { SmileWriteContext ctxt = _childToRecycle; if (ctxt == null) { _childToRecycle = ctxt = new SmileWriteContext(TYPE_ARRAY, this, (_dups == null) ? null : _dups.child(), currentValue); return ctxt; } return ctxt.reset(TYPE_ARRAY, currentValue); } public SmileWriteContext createChildObjectContext(Object currentValue) { SmileWriteContext ctxt = _childToRecycle; if (ctxt == null) { _childToRecycle = ctxt = new SmileWriteContext(TYPE_OBJECT, this, (_dups == null) ? null : _dups.child(), currentValue); return ctxt; } return ctxt.reset(TYPE_OBJECT, currentValue); } @Override public final SmileWriteContext getParent() { return _parent; } @Override public final String getCurrentName() { if (_gotFieldId) { return _currentName; } return null; } @Override public boolean hasCurrentName() { return _gotFieldId; }
Method that can be used to both clear the accumulated references (specifically value set with setCurrentValue(Object)) that should not be retained, and returns parent (as would getParent() do). Typically called when closing the active context when encountering JsonToken.END_ARRAY or JsonToken.END_OBJECT.
/** * Method that can be used to both clear the accumulated references * (specifically value set with {@link #setCurrentValue(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}. */
public SmileWriteContext clearAndGetParent() { _currentValue = null; // could also clear the current name, but seems cheap enough to leave? return _parent; } public DupDetector getDupDetector() { return _dups; }
Method that writer is to call before it writes a field name.
Returns:Ok if name writing should proceed
/** * Method that writer is to call before it writes a field name. * * @return Ok if name writing should proceed */
public boolean writeFieldName(String name) throws JsonProcessingException { if ((_type != TYPE_OBJECT) || _gotFieldId) { return false; } _gotFieldId = true; _currentName = name; if (_dups != null) { _checkDup(_dups, name); } return true; } private final void _checkDup(DupDetector dd, String name) throws JsonProcessingException { if (dd.isDup(name)) { Object src = dd.getSource(); throw new JsonGenerationException("Duplicate field '"+name+"'", ((src instanceof JsonGenerator) ? ((JsonGenerator) src) : null)); } } public boolean writeValue() { // Only limitation is with OBJECTs: if (_type == TYPE_OBJECT) { if (!_gotFieldId) { return false; } _gotFieldId = false; } ++_index; return true; } }