LachlanMcKee/gsonpath

Add polymorphism support to the generated code

Closed this issue · 1 comments

There is an example of polymorphism in the gsonpath-sample sub-module which demonstrates the usefulness of having polymorphism support via gson.

The benefit is that a json response that contains an array of elements that are not homogeneous to be deserialized into different classes.

The new feature would be to expose the ability to add polymorphism support to the library in such a way that the TypeAdapter factory used to facilitate the polymorphism can be localized to a specific class, meaning different of polymorphism can be used in different classes without being restrictive.

The proposed API changes would introduce a new annotation called GsonSubtype which can be used to annotate fields or methods (in the case of interfaces).

It would allow developers specify the field within the json object that specifies the type, and then delegate a class depending on the value. It should be possible to add type conditions based on Strings, Integers and Booleans.

E.g.

@GsonSubtype(
    fieldName = "type",
    failOnMissingKey = true, // This would throw an exception if an unexpected type appeared.
    stringKeys = {
        @GsonSubtype.StringKey(key = "type1", subtype = Type1.class),
        @GsonSubtype.StringKey(key = "type2", subtype = Type2.class),
        @GsonSubtype.StringKey(key = "type3", subtype = Type3.class)
    }
)
@GsonSubtype(
    fieldName = "type",
    failOnMissingKey = true, // This would throw an exception if an unexpected type appeared.
    integerKeys = {
        @GsonSubtype.IntegerKey(key = 0, subtype = Type1.class),
        @GsonSubtype.IntegerKey(key = 1, subtype = Type2.class),
        @GsonSubtype.IntegerKey(key = 2, subtype = Type3.class)
    }
)
@GsonSubtype(
    fieldName = "type",
    failOnMissingKey = true, // This would throw an exception if an unexpected type appeared.
    booleanKeys = {
        @GsonSubtype.BooleanKey(key = true, subtype = Type1.class),
        @GsonSubtype.BooleanKey(key = false, subtype = Type2.class)
    }
)

This new feature has been implemented and released