use of com.fasterxml.jackson.databind.util.TokenBuffer in project jackson-databind by FasterXML.
the class ObjectMapper method updateValue.
/**
* Convenience method similar to {@link #convertValue(Object, JavaType)} but one
* in which an existing value (`valueToUpdate`) is modified based on contents
* of serialization of another object (`updateWithValue`).
*<p>
* Implementation is approximately as follows:
*<ol>
* <li>Serialize `updateWithValue` into {@link TokenBuffer}</li>
* <li>Construct {@link ObjectReader} with `valueToUpdate` (using {@link #readerForUpdating(Object)})
* </li>
* <li>Construct {@link JsonParser} (using {@link TokenBuffer#asParser()})
* </li>
* <li>Update using {@link ObjectReader#readValue(JsonParser)}.
* </li>
* <li>Return `valueToUpdate`
* </li>
*</ol>
*<p>
* Note that update is "shallow" in that only first level of properties (or, immediate contents
* of container to update) are modified, unless properties themselves indicate that
* merging should be applied for contents. Such merging can be specified using
* annotations (see <code>JsonMerge</code>) as well as using "config overrides" (see
* {@link #configOverride(Class)} and {@link #setDefaultMergeable(Boolean)}).
*
* @param valueToUpdate Object to update
* @param updateWithValue Object to conceptually serialize and merge into value to
* update; can be thought of as a provider for overrides to apply.
*
* @return First argument, that is, `valueToUpdate`
*
* @throws JsonMappingException if there are structural incompatibilities that prevent update
*
* @since 2.9
*/
public <T> T updateValue(T valueToUpdate, Object updateWithValue) throws JsonMappingException {
if ((valueToUpdate == null) || (updateWithValue == null)) {
return valueToUpdate;
}
@SuppressWarnings("resource") TokenBuffer buf = new TokenBuffer(this, false);
if (isEnabled(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)) {
buf = buf.forceUseOfBigDecimal(true);
}
try {
SerializationConfig config = getSerializationConfig().without(SerializationFeature.WRAP_ROOT_VALUE);
_serializerProvider(config).serializeValue(buf, updateWithValue);
JsonParser p = buf.asParser();
readerForUpdating(valueToUpdate).readValue(p);
p.close();
} catch (IOException e) {
// should not occur, no real i/o...
if (e instanceof JsonMappingException) {
throw (JsonMappingException) e;
}
// 17-Mar-2017, tatu: Really ought not happen...
throw JsonMappingException.fromUnexpectedIOE(e);
}
return valueToUpdate;
}
use of com.fasterxml.jackson.databind.util.TokenBuffer in project jackson-databind by FasterXML.
the class AsPropertyTypeDeserializer method deserializeTypedFromObject.
/**
* This is the trickiest thing to handle, since property we are looking
* for may be anywhere...
*/
@Override
@SuppressWarnings("resource")
public Object deserializeTypedFromObject(JsonParser p, DeserializationContext ctxt) throws IOException {
// 02-Aug-2013, tatu: May need to use native type ids
if (p.canReadTypeId()) {
Object typeId = p.getTypeId();
if (typeId != null) {
return _deserializeWithNativeTypeId(p, ctxt, typeId);
}
}
// but first, sanity check to ensure we have START_OBJECT or FIELD_NAME
JsonToken t = p.getCurrentToken();
if (t == JsonToken.START_OBJECT) {
t = p.nextToken();
} else if (/*t == JsonToken.START_ARRAY ||*/
t != JsonToken.FIELD_NAME) {
/* This is most likely due to the fact that not all Java types are
* serialized as JSON Objects; so if "as-property" inclusion is requested,
* serialization of things like Lists must be instead handled as if
* "as-wrapper-array" was requested.
* But this can also be due to some custom handling: so, if "defaultImpl"
* is defined, it will be asked to handle this case.
*/
return _deserializeTypedUsingDefaultImpl(p, ctxt, null);
}
// Ok, let's try to find the property. But first, need token buffer...
TokenBuffer tb = null;
for (; t == JsonToken.FIELD_NAME; t = p.nextToken()) {
String name = p.getCurrentName();
// to point to the value
p.nextToken();
if (name.equals(_typePropertyName)) {
// gotcha!
return _deserializeTypedForId(p, ctxt, tb);
}
if (tb == null) {
tb = new TokenBuffer(p, ctxt);
}
tb.writeFieldName(name);
tb.copyCurrentStructure(p);
}
return _deserializeTypedUsingDefaultImpl(p, ctxt, tb);
}
use of com.fasterxml.jackson.databind.util.TokenBuffer in project jackson-databind by FasterXML.
the class AsWrapperTypeDeserializer method _deserialize.
/*
/***************************************************************
/* Internal methods
/***************************************************************
*/
/**
* Method that handles type information wrapper, locates actual
* subtype deserializer to use, and calls it to do actual
* deserialization.
*/
@SuppressWarnings("resource")
protected Object _deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
// 02-Aug-2013, tatu: May need to use native type ids
if (p.canReadTypeId()) {
Object typeId = p.getTypeId();
if (typeId != null) {
return _deserializeWithNativeTypeId(p, ctxt, typeId);
}
}
// first, sanity checks
JsonToken t = p.getCurrentToken();
if (t == JsonToken.START_OBJECT) {
// should always get field name, but just in case...
if (p.nextToken() != JsonToken.FIELD_NAME) {
ctxt.reportWrongTokenException(baseType(), JsonToken.FIELD_NAME, "need JSON String that contains type id (for subtype of " + baseTypeName() + ")");
}
} else if (t != JsonToken.FIELD_NAME) {
ctxt.reportWrongTokenException(baseType(), JsonToken.START_OBJECT, "need JSON Object to contain As.WRAPPER_OBJECT type information for class " + baseTypeName());
}
final String typeId = p.getText();
JsonDeserializer<Object> deser = _findDeserializer(ctxt, typeId);
p.nextToken();
// Minor complication: we may need to merge type id in?
if (_typeIdVisible && p.getCurrentToken() == JsonToken.START_OBJECT) {
// but what if there's nowhere to add it in? Error? Or skip? For now, skip.
TokenBuffer tb = new TokenBuffer(null, false);
// recreate START_OBJECT
tb.writeStartObject();
tb.writeFieldName(_typePropertyName);
tb.writeString(typeId);
// 02-Jul-2016, tatu: Depending on for JsonParserSequence is initialized it may
// try to access current token; ensure there isn't one
p.clearCurrentToken();
p = JsonParserSequence.createFlattened(false, tb.asParser(p), p);
p.nextToken();
}
Object value = deser.deserialize(p, ctxt);
// And then need the closing END_OBJECT
if (p.nextToken() != JsonToken.END_OBJECT) {
ctxt.reportWrongTokenException(baseType(), JsonToken.END_OBJECT, "expected closing END_OBJECT after type information and deserialized value");
}
return value;
}
use of com.fasterxml.jackson.databind.util.TokenBuffer in project jackson-databind by FasterXML.
the class BeanDeserializer method deserializeFromNull.
/**
* Helper method called for rare case of pointing to {@link JsonToken#VALUE_NULL}
* token. While this is most often an erroneous condition, there is one specific
* case with XML handling where polymorphic type with no properties is exposed
* as such, and should be handled same as empty Object.
*
* @since 2.7
*/
protected Object deserializeFromNull(JsonParser p, DeserializationContext ctxt) throws IOException {
// `VALUE_NULL` token.
if (p.requiresCustomCodec()) {
// not only XML module, but mostly it...
@SuppressWarnings("resource") TokenBuffer tb = new TokenBuffer(p, ctxt);
tb.writeEndObject();
JsonParser p2 = tb.asParser(p);
// to point to END_OBJECT
p2.nextToken();
// note: don't have ObjectId to consider at this point, so:
Object ob = _vanillaProcessing ? vanillaDeserialize(p2, ctxt, JsonToken.END_OBJECT) : deserializeFromObject(p2, ctxt);
p2.close();
return ob;
}
return ctxt.handleUnexpectedToken(handledType(), p);
}
use of com.fasterxml.jackson.databind.util.TokenBuffer in project jackson-databind by FasterXML.
the class BuilderBasedDeserializer method _deserializeUsingPropertyBased.
/**
* Method called to deserialize bean using "property-based creator":
* this means that a non-default constructor or factory method is
* called, and then possibly other setters. The trick is that
* values for creator method need to be buffered, first; and
* due to non-guaranteed ordering possibly some other properties
* as well.
*/
@Override
@SuppressWarnings("resource")
protected final Object _deserializeUsingPropertyBased(final JsonParser p, final DeserializationContext ctxt) throws IOException {
final PropertyBasedCreator creator = _propertyBasedCreator;
PropertyValueBuffer buffer = creator.startBuilding(p, ctxt, _objectIdReader);
final Class<?> activeView = _needViewProcesing ? ctxt.getActiveView() : null;
// 04-Jan-2010, tatu: May need to collect unknown properties for polymorphic cases
TokenBuffer unknown = null;
JsonToken t = p.getCurrentToken();
for (; t == JsonToken.FIELD_NAME; t = p.nextToken()) {
String propName = p.getCurrentName();
// to point to value
p.nextToken();
// creator property?
SettableBeanProperty creatorProp = creator.findCreatorProperty(propName);
if (creatorProp != null) {
if ((activeView != null) && !creatorProp.visibleInView(activeView)) {
p.skipChildren();
continue;
}
// Last creator property to set?
if (buffer.assignParameter(creatorProp, creatorProp.deserialize(p, ctxt))) {
// to move to following FIELD_NAME/END_OBJECT
p.nextToken();
Object bean;
try {
bean = creator.build(ctxt, buffer);
} catch (Exception e) {
wrapAndThrow(e, _beanType.getRawClass(), propName, ctxt);
// never gets here
continue;
}
// polymorphic?
if (bean.getClass() != _beanType.getRawClass()) {
return handlePolymorphic(p, ctxt, bean, unknown);
}
if (unknown != null) {
// nope, just extra unknown stuff...
bean = handleUnknownProperties(ctxt, bean, unknown);
}
// or just clean?
return _deserialize(p, ctxt, bean);
}
continue;
}
// Object Id property?
if (buffer.readIdProperty(propName)) {
continue;
}
// regular property? needs buffering
SettableBeanProperty prop = _beanProperties.find(propName);
if (prop != null) {
buffer.bufferProperty(prop, prop.deserialize(p, ctxt));
continue;
}
// passed to any setter
if (_ignorableProps != null && _ignorableProps.contains(propName)) {
handleIgnoredProperty(p, ctxt, handledType(), propName);
continue;
}
// "any property"?
if (_anySetter != null) {
buffer.bufferAnyProperty(_anySetter, propName, _anySetter.deserialize(p, ctxt));
continue;
}
// Ok then, let's collect the whole field; name and value
if (unknown == null) {
unknown = new TokenBuffer(p, ctxt);
}
unknown.writeFieldName(propName);
unknown.copyCurrentStructure(p);
}
// We hit END_OBJECT, so:
Object bean;
try {
bean = creator.build(ctxt, buffer);
} catch (Exception e) {
bean = wrapInstantiationProblem(e, ctxt);
}
if (unknown != null) {
// polymorphic?
if (bean.getClass() != _beanType.getRawClass()) {
return handlePolymorphic(null, ctxt, bean, unknown);
}
// no, just some extra unknown properties
return handleUnknownProperties(ctxt, bean, unknown);
}
return bean;
}
Aggregations