@Override public TypeDeserializer forProperty(BeanProperty prop) { // usually if it's null: return (prop == _property) ? this : new AsArrayTypeDeserializer(this, prop); }
/** * Method called when actual object is serialized as JSON Array. */ @Override public Object deserializeTypedFromArray(JsonParser jp, DeserializationContext ctxt) throws IOException { return _deserialize(jp, ctxt); }
Object typeId = p.getTypeId(); if (typeId != null) { return _deserializeWithNativeTypeId(p, ctxt, typeId); String typeId = _locateTypeId(p, ctxt); JsonDeserializer<Object> deser = _findDeserializer(ctxt, typeId); && !_usesExternalId() && p.getCurrentToken() == JsonToken.START_OBJECT) { ctxt.reportWrongTokenException(baseType(), JsonToken.END_ARRAY, "expected closing END_ARRAY after type information and deserialized value");
protected String _locateTypeId(JsonParser p, DeserializationContext ctxt) throws IOException { if (!p.isExpectedStartArrayToken()) { // Need to allow even more customized handling, if something unexpected seen... // but should there be a way to limit this to likely success cases? if (_defaultImpl != null) { return _idResolver.idFromBaseType(); } ctxt.reportWrongTokenException(baseType(), JsonToken.START_ARRAY, "need JSON Array to contain As.WRAPPER_ARRAY type information for class "+baseTypeName()); return null; } // And then type id as a String JsonToken t = p.nextToken(); if (t == JsonToken.VALUE_STRING) { String result = p.getText(); p.nextToken(); return result; } if (_defaultImpl != null) { return _idResolver.idFromBaseType(); } ctxt.reportWrongTokenException(baseType(), JsonToken.VALUE_STRING, "need JSON String that contains type id (for subtype of %s)", baseTypeName()); return null; }
/** * Method that handles type information wrapper, locates actual * subtype deserializer to use, and calls it to do actual * deserialization. */ private final Object _deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { boolean hadStartArray = jp.isExpectedStartArrayToken(); String typeId = _locateTypeId(jp, ctxt); JsonDeserializer<Object> deser = _findDeserializer(ctxt, typeId); // Minor complication: we may need to merge type id in? if (_typeIdVisible && jp.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); tb.writeStartObject(); // recreate START_OBJECT tb.writeFieldName(_typePropertyName); tb.writeString(typeId); jp = JsonParserSequence.createFlattened(tb.asParser(jp), jp); jp.nextToken(); } Object value = deser.deserialize(jp, ctxt); // And then need the closing END_ARRAY if (hadStartArray && jp.nextToken() != JsonToken.END_ARRAY) { throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY, "expected closing END_ARRAY after type information and deserialized value"); } return value; }
@Override public Object deserializeTypedFromAny(JsonParser p, DeserializationContext ctxt) throws IOException { /* Sometimes, however, we get an array wrapper; specifically * when an array or list has been serialized with type information. */ if (p.getCurrentToken() == JsonToken.START_ARRAY) { return super.deserializeTypedFromArray(p, ctxt); } return deserializeTypedFromObject(p, ctxt); }
return super.deserializeTypedFromAny(p, ctxt);
protected final String _locateTypeId(JsonParser jp, DeserializationContext ctxt) throws IOException { if (!jp.isExpectedStartArrayToken()) { // Need to allow even more customized handling, if something unexpected seen... // but should there be a way to limit this to likely success cases? if (_defaultImpl != null) { return _idResolver.idFromBaseType(); } throw ctxt.wrongTokenException(jp, JsonToken.START_ARRAY, "need JSON Array to contain As.WRAPPER_ARRAY type information for class "+baseTypeName()); } // And then type id as a String JsonToken t = jp.nextToken(); if (t == JsonToken.VALUE_STRING) { String result = jp.getText(); jp.nextToken(); return result; } if (_defaultImpl != null) { return _idResolver.idFromBaseType(); } throw ctxt.wrongTokenException(jp, JsonToken.VALUE_STRING, "need JSON String that contains type id (for subtype of "+baseTypeName()+")"); }
/** * Method that handles type information wrapper, locates actual * subtype deserializer to use, and calls it to do actual * deserialization. */ private final Object _deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { boolean hadStartArray = jp.isExpectedStartArrayToken(); String typeId = _locateTypeId(jp, ctxt); JsonDeserializer<Object> deser = _findDeserializer(ctxt, typeId); // Minor complication: we may need to merge type id in? if (_typeIdVisible && jp.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); tb.writeStartObject(); // recreate START_OBJECT tb.writeFieldName(_typePropertyName); tb.writeString(typeId); jp = JsonParserSequence.createFlattened(tb.asParser(jp), jp); jp.nextToken(); } Object value = deser.deserialize(jp, ctxt); // And then need the closing END_ARRAY if (hadStartArray && jp.nextToken() != JsonToken.END_ARRAY) { throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY, "expected closing END_ARRAY after type information and deserialized value"); } return value; }
@Override public Object deserializeTypedFromAny(JsonParser jp, DeserializationContext ctxt) throws IOException { /* [JACKSON-387]: Sometimes, however, we get an array wrapper; specifically * when an array or list has been serialized with type information. */ if (jp.getCurrentToken() == JsonToken.START_ARRAY) { return super.deserializeTypedFromArray(jp, ctxt); } return deserializeTypedFromObject(jp, ctxt); }
@SuppressWarnings("resource") protected Object _deserializeTypedUsingDefaultImpl(JsonParser jp, DeserializationContext ctxt, TokenBuffer tb) throws IOException { // As per [JACKSON-614], may have default implementation to use JsonDeserializer<Object> deser = _findDefaultImplDeserializer(ctxt); if (deser != null) { if (tb != null) { tb.writeEndObject(); jp = tb.asParser(jp); // must move to point to the first token: jp.nextToken(); } return deser.deserialize(jp, ctxt); } // or, perhaps we just bumped into a "natural" value (boolean/int/double/String)? Object result = TypeDeserializer.deserializeIfNatural(jp, ctxt, _baseType); if (result != null) { return result; } // or, something for which "as-property" won't work, changed into "wrapper-array" type: if (jp.getCurrentToken() == JsonToken.START_ARRAY) { return super.deserializeTypedFromAny(jp, ctxt); } throw ctxt.wrongTokenException(jp, JsonToken.FIELD_NAME, "missing property '"+_typePropertyName+"' that is to contain type id (for class "+baseTypeName()+")"); }
protected final String _locateTypeId(JsonParser jp, DeserializationContext ctxt) throws IOException { if (!jp.isExpectedStartArrayToken()) { // Need to allow even more customized handling, if something unexpected seen... // but should there be a way to limit this to likely success cases? if (_defaultImpl != null) { return _idResolver.idFromBaseType(); } throw ctxt.wrongTokenException(jp, JsonToken.START_ARRAY, "need JSON Array to contain As.WRAPPER_ARRAY type information for class "+baseTypeName()); } // And then type id as a String JsonToken t = jp.nextToken(); if (t == JsonToken.VALUE_STRING) { String result = jp.getText(); jp.nextToken(); return result; } if (_defaultImpl != null) { return _idResolver.idFromBaseType(); } throw ctxt.wrongTokenException(jp, JsonToken.VALUE_STRING, "need JSON String that contains type id (for subtype of "+baseTypeName()+")"); }
protected String _locateTypeId(JsonParser p, DeserializationContext ctxt) throws IOException { if (!p.isExpectedStartArrayToken()) { // Need to allow even more customized handling, if something unexpected seen... // but should there be a way to limit this to likely success cases? if (_defaultImpl != null) { return _idResolver.idFromBaseType(); } ctxt.reportWrongTokenException(baseType(), JsonToken.START_ARRAY, "need JSON Array to contain As.WRAPPER_ARRAY type information for class "+baseTypeName()); return null; } // And then type id as a String JsonToken t = p.nextToken(); if (t == JsonToken.VALUE_STRING) { String result = p.getText(); p.nextToken(); return result; } if (_defaultImpl != null) { return _idResolver.idFromBaseType(); } ctxt.reportWrongTokenException(baseType(), JsonToken.VALUE_STRING, "need JSON String that contains type id (for subtype of %s)", baseTypeName()); return null; }
Object typeId = p.getTypeId(); if (typeId != null) { return _deserializeWithNativeTypeId(p, ctxt, typeId); String typeId = _locateTypeId(p, ctxt); JsonDeserializer<Object> deser = _findDeserializer(ctxt, typeId); && !_usesExternalId() && p.getCurrentToken() == JsonToken.START_OBJECT) { ctxt.reportWrongTokenException(baseType(), JsonToken.END_ARRAY, "expected closing END_ARRAY after type information and deserialized value");
/** * Method called when actual object is serialized as JSON Object */ @Override public Object deserializeTypedFromObject(JsonParser jp, DeserializationContext ctxt) throws IOException { return _deserialize(jp, ctxt); }
@Override public TypeDeserializer buildTypeDeserializer(DeserializationConfig config, JavaType baseType, Collection<NamedType> subtypes) { if (_idType == JsonTypeInfo.Id.NONE) { return null; } // 03-Oct-2016, tatu: As per [databind#1395] better prevent use for primitives, // regardless of setting if (baseType.isPrimitive()) { return null; } TypeIdResolver idRes = idResolver(config, baseType, subtypes, false, true); JavaType defaultImpl = defineDefaultImpl(config, baseType); // First, method for converting type info to type id: switch (_includeAs) { case WRAPPER_ARRAY: return new AsArrayTypeDeserializer(baseType, idRes, _typeProperty, _typeIdVisible, defaultImpl); case PROPERTY: case EXISTING_PROPERTY: // as per [#528] same class as PROPERTY return new AsPropertyTypeDeserializer(baseType, idRes, _typeProperty, _typeIdVisible, defaultImpl, _includeAs); case WRAPPER_OBJECT: return new AsWrapperTypeDeserializer(baseType, idRes, _typeProperty, _typeIdVisible, defaultImpl); case EXTERNAL_PROPERTY: return new AsExternalTypeDeserializer(baseType, idRes, _typeProperty, _typeIdVisible, defaultImpl); } throw new IllegalStateException("Do not know how to construct standard type serializer for inclusion type: "+_includeAs); }
@Override public Object deserializeTypedFromAny(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { /* [JACKSON-387]: Sometimes, however, we get an array wrapper; specifically * when an array or list has been serialized with type information. */ if (jp.getCurrentToken() == JsonToken.START_ARRAY) { return super.deserializeTypedFromArray(jp, ctxt); } return deserializeTypedFromObject(jp, ctxt); }
protected Object _deserializeTypedUsingDefaultImpl(JsonParser jp, DeserializationContext ctxt, TokenBuffer tb) throws IOException, JsonProcessingException { // As per [JACKSON-614], may have default implementation to use if (_defaultImpl != null) { JsonDeserializer<Object> deser = _findDefaultImplDeserializer(ctxt); if (tb != null) { tb.writeEndObject(); jp = tb.asParser(jp); // must move to point to the first token: jp.nextToken(); } return deser.deserialize(jp, ctxt); } // or, perhaps we just bumped into a "natural" value (boolean/int/double/String)? Object result = _deserializeIfNatural(jp, ctxt); if (result != null) { return result; } // or, something for which "as-property" won't work, changed into "wrapper-array" type: if (jp.getCurrentToken() == JsonToken.START_ARRAY) { return super.deserializeTypedFromAny(jp, ctxt); } throw ctxt.wrongTokenException(jp, JsonToken.FIELD_NAME, "missing property '"+_typePropertyName+"' that is to contain type id (for class "+baseTypeName()+")"); }
protected final String _locateTypeId(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { if (!jp.isExpectedStartArrayToken()) { // [JACKSON-712] Need to allow even more customized handling, if something unexpected seen... // but should there be a way to limit this to likely success cases? if (_defaultImpl != null) { return _idResolver.idFromBaseType(); } throw ctxt.wrongTokenException(jp, JsonToken.START_ARRAY, "need JSON Array to contain As.WRAPPER_ARRAY type information for class "+baseTypeName()); } // And then type id as a String if (jp.nextToken() != JsonToken.VALUE_STRING) { if (_defaultImpl != null) { return _idResolver.idFromBaseType(); } throw ctxt.wrongTokenException(jp, JsonToken.VALUE_STRING, "need JSON String that contains type id (for subtype of "+baseTypeName()+")"); } String result = jp.getText(); jp.nextToken(); return result; } }
Object typeId = jp.getTypeId(); if (typeId != null) { return _deserializeWithNativeTypeId(jp, ctxt, typeId); String typeId = _locateTypeId(jp, ctxt); JsonDeserializer<Object> deser = _findDeserializer(ctxt, typeId); && !_usesExternalId() && jp.getCurrentToken() == JsonToken.START_OBJECT) {