com.fasterxml.jackson.databind.deser.std.StringArrayDeserializer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jersey-all Show documentation
Show all versions of jersey-all Show documentation
jersey-all is a rebundled verison of Jersey as one OSGi bundle.
package com.fasterxml.jackson.databind.deser.std;
import java.io.IOException;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
import com.fasterxml.jackson.databind.util.ObjectBuffer;
/**
* Separate implementation for serializing String arrays (instead of
* using {@link ObjectArrayDeserializer}.
* Used if (and only if) no custom value deserializers are used.
*/
@JacksonStdImpl
public final class StringArrayDeserializer
extends StdDeserializer
implements ContextualDeserializer
{
private static final long serialVersionUID = -7589512013334920693L;
public final static StringArrayDeserializer instance = new StringArrayDeserializer();
/**
* Value serializer to use, if not the standard one (which is inlined)
*/
protected JsonDeserializer _elementDeserializer;
public StringArrayDeserializer() {
super(String[].class);
_elementDeserializer = null;
}
@SuppressWarnings("unchecked")
protected StringArrayDeserializer(JsonDeserializer> deser) {
super(String[].class);
_elementDeserializer = (JsonDeserializer) deser;
}
@Override
public String[] deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
// Ok: must point to START_ARRAY (or equivalent)
if (!jp.isExpectedStartArrayToken()) {
return handleNonArray(jp, ctxt);
}
if (_elementDeserializer != null) {
return _deserializeCustom(jp, ctxt);
}
final ObjectBuffer buffer = ctxt.leaseObjectBuffer();
Object[] chunk = buffer.resetAndStart();
int ix = 0;
JsonToken t;
while ((t = jp.nextToken()) != JsonToken.END_ARRAY) {
// Ok: no need to convert Strings, but must recognize nulls
String value;
if (t == JsonToken.VALUE_STRING) {
value = jp.getText();
} else if (t == JsonToken.VALUE_NULL) {
value = null;
} else {
value = _parseString(jp, ctxt);
}
if (ix >= chunk.length) {
chunk = buffer.appendCompletedChunk(chunk);
ix = 0;
}
chunk[ix++] = value;
}
String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class);
ctxt.returnObjectBuffer(buffer);
return result;
}
/**
* Offlined version used when we do not use the default deserialization method.
*/
protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
final ObjectBuffer buffer = ctxt.leaseObjectBuffer();
Object[] chunk = buffer.resetAndStart();
final JsonDeserializer deser = _elementDeserializer;
int ix = 0;
JsonToken t;
while ((t = jp.nextToken()) != JsonToken.END_ARRAY) {
// Ok: no need to convert Strings, but must recognize nulls
String value = (t == JsonToken.VALUE_NULL) ? null : deser.deserialize(jp, ctxt);
if (ix >= chunk.length) {
chunk = buffer.appendCompletedChunk(chunk);
ix = 0;
}
chunk[ix++] = value;
}
String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class);
ctxt.returnObjectBuffer(buffer);
return result;
}
@Override
public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt,
TypeDeserializer typeDeserializer)
throws IOException, JsonProcessingException
{
return typeDeserializer.deserializeTypedFromArray(jp, ctxt);
}
private final String[] handleNonArray(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
// [JACKSON-526]: implicit arrays from single values?
if (!ctxt.isEnabled(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)) {
// [JACKSON-620] Empty String can become null...
if ((jp.getCurrentToken() == JsonToken.VALUE_STRING)
&& ctxt.isEnabled(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT)) {
String str = jp.getText();
if (str.length() == 0) {
return null;
}
}
throw ctxt.mappingException(_valueClass);
}
return new String[] { (jp.getCurrentToken() == JsonToken.VALUE_NULL) ? null : _parseString(jp, ctxt) };
}
/**
* Contextualization is needed to see whether we can "inline" deserialization
* of String values, or if we have to use separate value deserializer.
*/
@Override
public JsonDeserializer> createContextual(DeserializationContext ctxt,
BeanProperty property) throws JsonMappingException
{
JsonDeserializer> deser = _elementDeserializer;
// #125: May have a content converter
deser = findConvertingContentDeserializer(ctxt, property, deser);
if (deser == null) {
deser = ctxt.findContextualValueDeserializer(ctxt.constructType(String.class), property);
} else { // if directly assigned, probably not yet contextual, so:
deser = ctxt.handleSecondaryContextualization(deser, property);
}
// Ok ok: if all we got is the default String deserializer, can just forget about it
if (deser != null && this.isDefaultDeserializer(deser)) {
deser = null;
}
if (_elementDeserializer != deser) {
return new StringArrayDeserializer(deser);
}
return this;
}
}