Class RecordConverter<T>
- Type Parameters:
T- the record type
- All Implemented Interfaces:
JsonDeserializer,JsonSerializer<T>
A RecordConverter is built for the raw type (class) of a record, so a single instance handles all parameterized types for that raw type.
Serialization is based on the run-time classes of all values and so is straightforward.
For deserialization, at run time (potential optimization: at selection time) the deserializer is used for a concrete parameterized type. This type must be concrete in the sense that it cannot contain type variables anymore (nor wildcards -- we do not support those anyway). If the field that uses the record type *did* use type variables, then these must have been replaced by concrete types before passing on to this deserializer. So at this point the record type has an ordered list of named type parameters, and the concrete type binds them to an ordered list of concrete type arguments.
This deserializer then goes through the record fields. Each field potentially uses type variables, and all these must have been declared as type parameters by the record -- type variables (as opposed to the types they are bound to) do not cross the boundaries of a single record definition, and fields cannot define their own type variables.
For each record field, the field type is "concretized" -- replaced by a like-structured type in which type variables have been replaced by the types they are bound to. A single type variable is looked up in the record's type parameters by name, then the type argument at the same index is bound to the variable.
Finally, the fields get deserialized from the JSON fields using the deserializers for the resulting concrete types.
-
Nested Class Summary
Nested Classes -
Constructor Summary
ConstructorsConstructorDescriptionRecordConverter(Class<T> clazz, JsonRegistries registries) Application code usually does not have to call this constructor because instances of this class will be auto-generated for unknown records, and this constructor does not add any features on top of that.RecordConverter(Class<T> clazz, JsonRegistries registries, RecordConverter.Options options) This constructor adds extra options. -
Method Summary
Modifier and TypeMethodDescriptiondeserialize(com.google.gson.JsonElement json, Type recordType) Converts a value from JSON.com.google.gson.JsonElementConverts a value to JSON.booleansupportsClassForSerialization(Class<?> clazz) Checks if this serializer supports the specified class.booleanChecks if this deserializer supports the specified type.Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface name.martingeisse.grumpyjson.deserialize.JsonDeserializer
deserializeAbsentMethods inherited from interface name.martingeisse.grumpyjson.serialize.JsonSerializer
serializeOptional
-
Constructor Details
-
RecordConverter
Application code usually does not have to call this constructor because instances of this class will be auto-generated for unknown records, and this constructor does not add any features on top of that.- Parameters:
clazz- the record classregistries- the JSON registries -- needed to fetch the converters for field types at run-time
-
RecordConverter
This constructor adds extra options. Application code can create custom record converters manually using this constructor in cases where the auto-generated ones are not sufficient.- Parameters:
clazz- the record classregistries- the JSON registries -- needed to fetch the converters for field types at run-timeoptions- options that control the conversion from and to JSON
-
-
Method Details
-
supportsTypeForDeserialization
Description copied from interface:JsonDeserializerChecks if this deserializer supports the specified type.- Specified by:
supportsTypeForDeserializationin interfaceJsonDeserializer- Parameters:
type- the type to check- Returns:
- true if supported, false if not
-
deserialize
public T deserialize(com.google.gson.JsonElement json, Type recordType) throws JsonDeserializationException Description copied from interface:JsonDeserializerConverts a value from JSON.This method must not be called with a type for which
JsonDeserializer.supportsTypeForDeserialization(Type)returns false. Calling it with such types anyway results in undefined behavior.- Specified by:
deserializein interfaceJsonDeserializer- Parameters:
json- the JSONrecordType- the type to deserialize- Returns:
- the deserialized value
- Throws:
JsonDeserializationException- if the JSON does not match the expected structure
-
supportsClassForSerialization
Description copied from interface:JsonSerializerChecks if this serializer supports the specified class.- Specified by:
supportsClassForSerializationin interfaceJsonSerializer<T>- Parameters:
clazz- the class to check- Returns:
- true if supported, false if not
-
serialize
Description copied from interface:JsonSerializerConverts a value to JSON.This method must not be called with values for whose class
JsonSerializer.supportsClassForSerialization(Class)returns false. Calling it with such values anyway results in undefined behavior.This method is not supported for values that can vanish during serialization, such as
OptionalField--JsonSerializer.serializeOptional(Object)should be called instead. If this method is called with such values anyway, it should always fail, even when the value does not vanish, to capture bugs early. Examples where this happens: - in a list of OptionalFields. While we could simply remove vanishing elements, doing so is just a weird way of filtering the list before serialization, which can be done the usual way. Moreover, there is no useful interpretation of a list-of-OptionalField during deserialization since all elements found in the JSON are known to be present, and vanishing elements cannot be found. - when turning a top-level OptionalField to JSON - when nesting two OptionalFields- Specified by:
serializein interfaceJsonSerializer<T>- Parameters:
record- the value to convert to JSON- Returns:
- the generated JSON
-