Skip to content

Commit

Permalink
Improve access to JsonFormat.Value by (de)serializers, to support u…
Browse files Browse the repository at this point in the history
…pcoming per-type defaulting
  • Loading branch information
cowtowncoder committed Mar 20, 2016
1 parent bb8a0b3 commit f442893
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.util.StdDateFormat;

/**
Expand Down Expand Up @@ -104,7 +103,8 @@ public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanPro
throws JsonMappingException
{
if (property != null) {
JsonFormat.Value format = ctxt.getAnnotationIntrospector().findFormat((Annotated) property.getMember());
JsonFormat.Value format = findFormatOverrides(ctxt, property,
this.handledType());
if (format != null) {
TimeZone tz = format.getTimeZone();
// First: fully custom pattern?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,9 @@ protected boolean isDefaultKeyDeserializer(KeyDeserializer keyDeser) {
* this method if they are to handle type information.
*/
@Override
public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws IOException {
return typeDeserializer.deserializeTypedFromAny(jp, ctxt);
public Object deserializeWithType(JsonParser p, DeserializationContext ctxt,
TypeDeserializer typeDeserializer) throws IOException {
return typeDeserializer.deserializeTypedFromAny(p, ctxt);
}

/*
Expand All @@ -128,24 +129,24 @@ public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt, Ty
/**********************************************************
*/

protected final boolean _parseBooleanPrimitive(JsonParser jp, DeserializationContext ctxt) throws IOException
protected final boolean _parseBooleanPrimitive(JsonParser p, DeserializationContext ctxt) throws IOException
{
JsonToken t = jp.getCurrentToken();
JsonToken t = p.getCurrentToken();
if (t == JsonToken.VALUE_TRUE) return true;
if (t == JsonToken.VALUE_FALSE) return false;
if (t == JsonToken.VALUE_NULL) return false;

// [JACKSON-78]: should accept ints too, (0 == false, otherwise true)
if (t == JsonToken.VALUE_NUMBER_INT) {
// 11-Jan-2012, tatus: May be outside of int...
if (jp.getNumberType() == NumberType.INT) {
return (jp.getIntValue() != 0);
if (p.getNumberType() == NumberType.INT) {
return (p.getIntValue() != 0);
}
return _parseBooleanFromOther(jp, ctxt);
return _parseBooleanFromOther(p, ctxt);
}
// And finally, let's allow Strings to be converted too
if (t == JsonToken.VALUE_STRING) {
String text = jp.getText().trim();
String text = p.getText().trim();
// [#422]: Allow aliases
if ("true".equals(text) || "True".equals(text)) {
return true;
Expand All @@ -160,11 +161,11 @@ protected final boolean _parseBooleanPrimitive(JsonParser jp, DeserializationCon
}
// [databind#381]
if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
jp.nextToken();
final boolean parsed = _parseBooleanPrimitive(jp, ctxt);
t = jp.nextToken();
p.nextToken();
final boolean parsed = _parseBooleanPrimitive(p, ctxt);
t = p.nextToken();
if (t != JsonToken.END_ARRAY) {
throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY,
throw ctxt.wrongTokenException(p, JsonToken.END_ARRAY,
"Attempted to unwrap single value array for single 'boolean' value but there was more than a single value in the array");
}
return parsed;
Expand Down Expand Up @@ -344,10 +345,10 @@ protected Short _parseShort(JsonParser p, DeserializationContext ctxt)
throw ctxt.mappingException(_valueClass, t);
}

protected final short _parseShortPrimitive(JsonParser jp, DeserializationContext ctxt)
protected final short _parseShortPrimitive(JsonParser p, DeserializationContext ctxt)
throws IOException
{
int value = _parseIntPrimitive(jp, ctxt);
int value = _parseIntPrimitive(p, ctxt);
// So far so good: but does it fit?
if (value < Short.MIN_VALUE || value > Short.MAX_VALUE) {
throw ctxt.weirdStringException(String.valueOf(value),
Expand Down Expand Up @@ -543,18 +544,18 @@ protected final long _parseLongPrimitive(JsonParser p, DeserializationContext ct
throw ctxt.mappingException(_valueClass, p.getCurrentToken());
}

protected final Float _parseFloat(JsonParser jp, DeserializationContext ctxt)
protected final Float _parseFloat(JsonParser p, DeserializationContext ctxt)
throws IOException
{
// We accept couple of different types; obvious ones first:
JsonToken t = jp.getCurrentToken();
JsonToken t = p.getCurrentToken();

if (t == JsonToken.VALUE_NUMBER_INT || t == JsonToken.VALUE_NUMBER_FLOAT) { // coercing should work too
return jp.getFloatValue();
return p.getFloatValue();
}
// And finally, let's allow Strings to be converted too
if (t == JsonToken.VALUE_STRING) {
String text = jp.getText().trim();
String text = p.getText().trim();
if (text.length() == 0) {
return (Float) getEmptyValue(ctxt);
}
Expand Down Expand Up @@ -588,11 +589,11 @@ protected final Float _parseFloat(JsonParser jp, DeserializationContext ctxt)
}
// Issue#381
if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
jp.nextToken();
final Float parsed = _parseFloat(jp, ctxt);
t = jp.nextToken();
p.nextToken();
final Float parsed = _parseFloat(p, ctxt);
t = p.nextToken();
if (t != JsonToken.END_ARRAY) {
throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY,
throw ctxt.wrongTokenException(p, JsonToken.END_ARRAY,
"Attempted to unwrap single value array for single 'Byte' value but there was more than a single value in the array");
}
return parsed;
Expand All @@ -601,16 +602,16 @@ protected final Float _parseFloat(JsonParser jp, DeserializationContext ctxt)
throw ctxt.mappingException(_valueClass, t);
}

protected final float _parseFloatPrimitive(JsonParser jp, DeserializationContext ctxt)
protected final float _parseFloatPrimitive(JsonParser p, DeserializationContext ctxt)
throws IOException
{
JsonToken t = jp.getCurrentToken();
JsonToken t = p.getCurrentToken();

if (t == JsonToken.VALUE_NUMBER_INT || t == JsonToken.VALUE_NUMBER_FLOAT) { // coercing should work too
return jp.getFloatValue();
return p.getFloatValue();
}
if (t == JsonToken.VALUE_STRING) {
String text = jp.getText().trim();
String text = p.getText().trim();
if (text.length() == 0 || _hasTextualNull(text)) {
return 0.0f;
}
Expand Down Expand Up @@ -639,11 +640,11 @@ protected final float _parseFloatPrimitive(JsonParser jp, DeserializationContext
}
// Issue#381
if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
jp.nextToken();
final float parsed = _parseFloatPrimitive(jp, ctxt);
t = jp.nextToken();
p.nextToken();
final float parsed = _parseFloatPrimitive(p, ctxt);
t = p.nextToken();
if (t != JsonToken.END_ARRAY) {
throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY,
throw ctxt.wrongTokenException(p, JsonToken.END_ARRAY,
"Attempted to unwrap single value array for single 'float' value but there was more than a single value in the array");
}
return parsed;
Expand All @@ -652,16 +653,16 @@ protected final float _parseFloatPrimitive(JsonParser jp, DeserializationContext
throw ctxt.mappingException(_valueClass, t);
}

protected final Double _parseDouble(JsonParser jp, DeserializationContext ctxt)
protected final Double _parseDouble(JsonParser p, DeserializationContext ctxt)
throws IOException
{
JsonToken t = jp.getCurrentToken();
JsonToken t = p.getCurrentToken();

if (t == JsonToken.VALUE_NUMBER_INT || t == JsonToken.VALUE_NUMBER_FLOAT) { // coercing should work too
return jp.getDoubleValue();
return p.getDoubleValue();
}
if (t == JsonToken.VALUE_STRING) {
String text = jp.getText().trim();
String text = p.getText().trim();
if (text.length() == 0) {
return (Double) getEmptyValue(ctxt);
}
Expand Down Expand Up @@ -694,11 +695,11 @@ protected final Double _parseDouble(JsonParser jp, DeserializationContext ctxt)
return (Double) getNullValue(ctxt);
}
if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
jp.nextToken();
final Double parsed = _parseDouble(jp, ctxt);
t = jp.nextToken();
p.nextToken();
final Double parsed = _parseDouble(p, ctxt);
t = p.nextToken();
if (t != JsonToken.END_ARRAY) {
throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY,
throw ctxt.wrongTokenException(p, JsonToken.END_ARRAY,
"Attempted to unwrap single value array for single 'Double' value but there was more than a single value in the array");
}
return parsed;
Expand All @@ -707,18 +708,18 @@ protected final Double _parseDouble(JsonParser jp, DeserializationContext ctxt)
throw ctxt.mappingException(_valueClass, t);
}

protected final double _parseDoublePrimitive(JsonParser jp, DeserializationContext ctxt)
protected final double _parseDoublePrimitive(JsonParser p, DeserializationContext ctxt)
throws IOException
{
// We accept couple of different types; obvious ones first:
JsonToken t = jp.getCurrentToken();
JsonToken t = p.getCurrentToken();

if (t == JsonToken.VALUE_NUMBER_INT || t == JsonToken.VALUE_NUMBER_FLOAT) { // coercing should work too
return jp.getDoubleValue();
return p.getDoubleValue();
}
// And finally, let's allow Strings to be converted too
if (t == JsonToken.VALUE_STRING) {
String text = jp.getText().trim();
String text = p.getText().trim();
if (text.length() == 0 || _hasTextualNull(text)) {
return 0.0;
}
Expand Down Expand Up @@ -749,11 +750,11 @@ protected final double _parseDoublePrimitive(JsonParser jp, DeserializationConte
}
// Issue#381
if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
jp.nextToken();
final double parsed = _parseDoublePrimitive(jp, ctxt);
t = jp.nextToken();
p.nextToken();
final double parsed = _parseDoublePrimitive(p, ctxt);
t = p.nextToken();
if (t != JsonToken.END_ARRAY) {
throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY,
throw ctxt.wrongTokenException(p, JsonToken.END_ARRAY,
"Attempted to unwrap single value array for single 'Byte' value but there was more than a single value in the array");
}
return parsed;
Expand All @@ -762,12 +763,12 @@ protected final double _parseDoublePrimitive(JsonParser jp, DeserializationConte
throw ctxt.mappingException(_valueClass, t);
}

protected java.util.Date _parseDate(JsonParser jp, DeserializationContext ctxt)
protected java.util.Date _parseDate(JsonParser p, DeserializationContext ctxt)
throws IOException
{
JsonToken t = jp.getCurrentToken();
JsonToken t = p.getCurrentToken();
if (t == JsonToken.VALUE_NUMBER_INT) {
return new java.util.Date(jp.getLongValue());
return new java.util.Date(p.getLongValue());
}
if (t == JsonToken.VALUE_NULL) {
return (java.util.Date) getNullValue(ctxt);
Expand All @@ -776,7 +777,7 @@ protected java.util.Date _parseDate(JsonParser jp, DeserializationContext ctxt)
String value = null;
try {
// As per [JACKSON-203], take empty Strings to mean
value = jp.getText().trim();
value = p.getText().trim();
if (value.length() == 0) {
return (Date) getEmptyValue(ctxt);
}
Expand All @@ -791,11 +792,11 @@ protected java.util.Date _parseDate(JsonParser jp, DeserializationContext ctxt)
}
// Issue#381
if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
jp.nextToken();
final Date parsed = _parseDate(jp, ctxt);
t = jp.nextToken();
p.nextToken();
final Date parsed = _parseDate(p, ctxt);
t = p.nextToken();
if (t != JsonToken.END_ARRAY) {
throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY,
throw ctxt.wrongTokenException(p, JsonToken.END_ARRAY,
"Attempted to unwrap single value array for single 'java.util.Date' value but there was more than a single value in the array");
}
return parsed;
Expand Down Expand Up @@ -851,21 +852,21 @@ protected final String _parseString(JsonParser p, DeserializationContext ctxt) t
*
* @since 2.5
*/
protected T _deserializeFromEmpty(JsonParser jp, DeserializationContext ctxt)
protected T _deserializeFromEmpty(JsonParser p, DeserializationContext ctxt)
throws IOException
{
JsonToken t = jp.getCurrentToken();
JsonToken t = p.getCurrentToken();
if (t == JsonToken.START_ARRAY) {
if (ctxt.isEnabled(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT)) {
t = jp.nextToken();
t = p.nextToken();
if (t == JsonToken.END_ARRAY) {
return null;
}
throw ctxt.mappingException(handledType(), JsonToken.START_ARRAY);
}
} else if (t == JsonToken.VALUE_STRING) {
if (ctxt.isEnabled(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT)) {
String str = jp.getText().trim();
String str = p.getText().trim();
if (str.isEmpty()) {
return null;
}
Expand Down Expand Up @@ -1061,22 +1062,22 @@ protected Boolean findFormatFeature(DeserializationContext ctxt,
* <b>must</b> be passed since it may be something other than what
* context has. Prior versions did not include the first parameter.
*
* @param jp Parser that points to value of the unknown property
* @param p Parser that points to value of the unknown property
* @param ctxt Context for deserialization; allows access to the parser,
* error reporting functionality
* @param instanceOrClass Instance that is being populated by this
* deserializer, or if not known, Class that would be instantiated.
* If null, will assume type is what {@link #getValueClass} returns.
* @param propName Name of the property that can not be mapped
*/
protected void handleUnknownProperty(JsonParser jp, DeserializationContext ctxt, Object instanceOrClass, String propName)
protected void handleUnknownProperty(JsonParser p, DeserializationContext ctxt, Object instanceOrClass, String propName)
throws IOException
{
if (instanceOrClass == null) {
instanceOrClass = handledType();
}
// Maybe we have configured handler(s) to take care of it?
if (ctxt.handleUnknownProperty(jp, this, instanceOrClass, propName)) {
if (ctxt.handleUnknownProperty(p, this, instanceOrClass, propName)) {
return;
}
// Nope, not handled. Potentially that's a problem...
Expand All @@ -1085,13 +1086,13 @@ protected void handleUnknownProperty(JsonParser jp, DeserializationContext ctxt,
/* But if we do get this far, need to skip whatever value we
* are pointing to now.
*/
jp.skipChildren();
p.skipChildren();
}

protected void _failDoubleToIntCoercion(JsonParser jp, DeserializationContext ctxt,
protected void _failDoubleToIntCoercion(JsonParser p, DeserializationContext ctxt,
String type) throws IOException
{
throw ctxt.mappingException("Can not coerce a floating-point value ('%s') into %s; enable `DeserializationFeature.ACCEPT_FLOAT_AS_INT` to allow",
jp.getValueAsString(), type);
p.getValueAsString(), type);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ public JsonSerializer<?> createContextual(SerializerProvider serializers,
BeanProperty property) throws JsonMappingException
{
if (property != null) {
JsonFormat.Value format = serializers.getAnnotationIntrospector().findFormat((Annotated)property.getMember());
JsonFormat.Value format = findFormatOverrides(serializers, property,
handledType());
if (format != null) {

// Simple case first: serialize as numeric timestamp?
JsonFormat.Shape shape = format.getShape();
if (shape.isNumeric()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonStringFormatVisitor;
import com.fasterxml.jackson.databind.node.ArrayNode;
Expand Down Expand Up @@ -96,10 +95,12 @@ public static EnumSerializer construct(Class<?> enumClass, SerializationConfig c
* choice here, however.
*/
@Override
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException
public JsonSerializer<?> createContextual(SerializerProvider serializers,
BeanProperty property) throws JsonMappingException
{
if (property != null) {
JsonFormat.Value format = prov.getAnnotationIntrospector().findFormat((Annotated) property.getMember());
JsonFormat.Value format = findFormatOverrides(serializers,
property, handledType());
if (format != null) {
Boolean serializeAsIndex = _isShapeWrittenUsingIndex(property.getType().getRawClass(), format, false);
if (serializeAsIndex != _serializeAsIndex) {
Expand Down

0 comments on commit f442893

Please sign in to comment.