package com.fasterxml.jackson.core.json;

import com.fasterxml.jackson.core.*;

Extension of JsonStreamContext, which implements core methods needed, and also exposes more complete API to generator implementation classes.
/** * Extension of {@link JsonStreamContext}, which implements * core methods needed, and also exposes * more complete API to generator implementation classes. */
public class JsonWriteContext extends JsonStreamContext { // // // Return values for writeValue() public final static int STATUS_OK_AS_IS = 0; public final static int STATUS_OK_AFTER_COMMA = 1; public final static int STATUS_OK_AFTER_COLON = 2; public final static int STATUS_OK_AFTER_SPACE = 3; // in root context public final static int STATUS_EXPECT_VALUE = 4; public final static int STATUS_EXPECT_NAME = 5;
Parent context for this context; null for root context.
/** * Parent context for this context; null for root context. */
protected final JsonWriteContext _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 JsonWriteContext _child; /* /********************************************************** /* 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;
Since:2.5
/** * @since 2.5 */
protected Object _currentValue;
Marker used to indicate that we just wrote a name, and now expect a value to write
/** * Marker used to indicate that we just wrote a name, and * now expect a value to write */
protected boolean _gotName; /* /********************************************************** /* Life-cycle /********************************************************** */ protected JsonWriteContext(int type, JsonWriteContext parent, DupDetector dups) { super(); _type = type; _parent = parent; _dups = dups; _index = -1; } /* @since 2.10 */ protected JsonWriteContext(int type, JsonWriteContext parent, DupDetector dups, Object currValue) { super(); _type = type; _parent = parent; _dups = dups; _index = -1; _currentValue = currValue; }
Internal method to allow instance reuse: DO NOT USE unless you absolutely know what you are doing. Clears up state (including "current value"), changes type to one specified; resets current duplicate-detection state (if any). Parent link left as-is since it is final.

NOTE: Public since 2.12.

/** * Internal method to allow instance reuse: DO NOT USE unless you absolutely * know what you are doing. * Clears up state (including "current value"), changes type to one specified; * resets current duplicate-detection state (if any). * Parent link left as-is since it is {@code final}. *<p> * NOTE: Public since 2.12. */
public JsonWriteContext reset(int type) { _type = type; _index = -1; _currentName = null; _gotName = false; _currentValue = null; if (_dups != null) { _dups.reset(); } return this; }
Internal method to allow instance reuse: DO NOT USE unless you absolutely know what you are doing. Clears up state, changes type to one specified, assigns "current value"; resets current duplicate-detection state (if any). Parent link left as-is since it is final.

NOTE: Public since 2.12.

Since:2.10
/** * Internal method to allow instance reuse: DO NOT USE unless you absolutely * know what you are doing. * Clears up state, changes type to one specified, assigns "current value"; * resets current duplicate-detection state (if any). * Parent link left as-is since it is {@code final}. *<p> * NOTE: Public since 2.12. * * @since 2.10 */
public JsonWriteContext reset(int type, Object currValue) { _type = type; _index = -1; _currentName = null; _gotName = false; _currentValue = currValue; if (_dups != null) { _dups.reset(); } return this; } public JsonWriteContext withDupDetector(DupDetector dups) { _dups = dups; return this; } @Override public Object getCurrentValue() { return _currentValue; } @Override public void setCurrentValue(Object v) { _currentValue = v; } /* /********************************************************** /* Factory methods /********************************************************** */
Deprecated:Since 2.3; use method that takes argument
/** * @deprecated Since 2.3; use method that takes argument */
@Deprecated public static JsonWriteContext createRootContext() { return createRootContext(null); } public static JsonWriteContext createRootContext(DupDetector dd) { return new JsonWriteContext(TYPE_ROOT, null, dd); } public JsonWriteContext createChildArrayContext() { JsonWriteContext ctxt = _child; if (ctxt == null) { _child = ctxt = new JsonWriteContext(TYPE_ARRAY, this, (_dups == null) ? null : _dups.child()); return ctxt; } return ctxt.reset(TYPE_ARRAY); } /* @since 2.10 */ public JsonWriteContext createChildArrayContext(Object currValue) { JsonWriteContext ctxt = _child; if (ctxt == null) { _child = ctxt = new JsonWriteContext(TYPE_ARRAY, this, (_dups == null) ? null : _dups.child(), currValue); return ctxt; } return ctxt.reset(TYPE_ARRAY, currValue); } public JsonWriteContext createChildObjectContext() { JsonWriteContext ctxt = _child; if (ctxt == null) { _child = ctxt = new JsonWriteContext(TYPE_OBJECT, this, (_dups == null) ? null : _dups.child()); return ctxt; } return ctxt.reset(TYPE_OBJECT); } /* @since 2.10 */ public JsonWriteContext createChildObjectContext(Object currValue) { JsonWriteContext ctxt = _child; if (ctxt == null) { _child = ctxt = new JsonWriteContext(TYPE_OBJECT, this, (_dups == null) ? null : _dups.child(), currValue); return ctxt; } return ctxt.reset(TYPE_OBJECT, currValue); } @Override public final JsonWriteContext getParent() { return _parent; } @Override public final String getCurrentName() { return _currentName; } // @since 2.9 @Override public boolean hasCurrentName() { return _currentName != null; }
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.
Since:2.7
/** * 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}. * * @since 2.7 */
public JsonWriteContext 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:Index of the field entry (0-based)
/** * Method that writer is to call before it writes a field name. * * @return Index of the field entry (0-based) */
public int writeFieldName(String name) throws JsonProcessingException { if ((_type != TYPE_OBJECT) || _gotName) { return STATUS_EXPECT_VALUE; } _gotName = true; _currentName = name; if (_dups != null) { _checkDup(_dups, name); } return (_index < 0) ? STATUS_OK_AS_IS : STATUS_OK_AFTER_COMMA; } 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 int writeValue() { // Most likely, object: if (_type == TYPE_OBJECT) { if (!_gotName) { return STATUS_EXPECT_NAME; } _gotName = false; ++_index; return STATUS_OK_AFTER_COLON; } // Ok, array? if (_type == TYPE_ARRAY) { int ix = _index; ++_index; return (ix < 0) ? STATUS_OK_AS_IS : STATUS_OK_AFTER_COMMA; } // Nope, root context // No commas within root context, but need space ++_index; return (_index == 0) ? STATUS_OK_AS_IS : STATUS_OK_AFTER_SPACE; } }