mbknor-jackson-jsonSchema icon indicating copy to clipboard operation
mbknor-jackson-jsonSchema copied to clipboard

Adding description field to @JsonSubTypes.Type

Open manticorps opened this issue 6 years ago • 3 comments

When we use inherance of object, the field description is not set in the properties of the polymorphic object.

There is a minimal example

<dependency>
    <groupId>com.kjetland</groupId>
    <artifactId>mbknor-jackson-jsonschema_2.13.0-M5</artifactId>
    <version>1.0.34</version>
</dependency>
package ch.swissdotnet.osp.integration;

import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.kjetland.jackson.jsonSchema.JsonSchemaGenerator;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DemoIssue {

    // SLF4J Logger
    private static final Logger LOG = LoggerFactory.getLogger(DemoIssue.class);

    private static ObjectMapper createObjectMapper() {

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(objectMapper.getSerializationConfig()
                                       .getDefaultVisibilityChecker()
                                       .withCreatorVisibility(JsonAutoDetect.Visibility.NONE)
                                       .withGetterVisibility(JsonAutoDetect.Visibility.NONE)
                                       .withIsGetterVisibility(JsonAutoDetect.Visibility.NONE)
                                       .withSetterVisibility(JsonAutoDetect.Visibility.NONE)
                                       .withFieldVisibility(JsonAutoDetect.Visibility.ANY));

        objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        return objectMapper;
    }

    @Test
    @Ignore
    public void example() throws JsonProcessingException {
        ObjectMapper MAPPER = createObjectMapper();
        JsonSchemaGenerator jsonSchemaGenerator = new JsonSchemaGenerator(MAPPER);
        JsonNode jsonSchema = jsonSchemaGenerator.generateJsonSchema(Waveform.class);
        System.out.println(MAPPER.writeValueAsString(jsonSchema));
    }

    @JsonTypeInfo (
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.EXISTING_PROPERTY,
        property = "type")
    @JsonSubTypes ({
        @JsonSubTypes.Type (value = Triangular.class, name = "TRIANGULAR"),
        @JsonSubTypes.Type (value = Square.class, name = "SQUARE"),
    })
    public abstract class Waveform {

        public abstract Type getType();
    }

    public class Triangular extends Waveform {

        @Deprecated // Used for serialization only.
        public Triangular() {
        }

        @Override
        public Type getType() {
            return Type.TRIANGLE;
        }
    }

    public class Square extends Waveform {

        @Deprecated // Used for serialization only.
        public Square() {
        }

        @Override
        public Type getType() {
            return Type.SQUARE;
        }
    }

    public enum Type {
        @JsonPropertyDescription("This is a triangle")
        TRIANGLE,
        @JsonPropertyDescription("This is a square")
        SQUARE
    }
}

And the output :

{
 "$schema" : "http://json-schema.org/draft-04/schema#",
 "title" : "Waveform",
 "oneOf" : [ {
   "$ref" : "#/definitions/Triangular"
 }, {
   "$ref" : "#/definitions/Square"
 } ],
 "definitions" : {
   "Triangular" : {
     "type" : "object",
     "additionalProperties" : false,
     "properties" : {
       "type" : {
         "type" : "string",
         "enum" : [ "TRIANGULAR" ],
         "default" : "TRIANGULAR"
       }
     },
     "title" : "TRIANGULAR",
     "required" : [ "type" ]
   },
   "Square" : {
     "type" : "object",
     "additionalProperties" : false,
     "properties" : {
       "type" : {
         "type" : "string",
         "enum" : [ "SQUARE" ],
         "default" : "SQUARE"
       }
     },
     "title" : "SQUARE",
     "required" : [ "type" ]
   }
 }
}

I expect to have the field type with the content :

"type" : {
          "type" : "string",
          "enum" : [ "TRIANGULAR" ],
          "default" : "TRIANGULAR",
          "description": "This is a triangle"
        }

I have the feeling there is need to add some code on the polymorphic method (~line 955) to add the description.

manticorps avatar Oct 29 '19 10:10 manticorps

Can you please supply how you would expect that the entire generated schema would look like?

mbknor avatar Nov 18 '19 21:11 mbknor

This issue is possibly related to #104

mbknor avatar Nov 18 '19 21:11 mbknor

Sorry for the delay, I have miss your response.

{
 "$schema" : "http://json-schema.org/draft-04/schema#",
 "title" : "Waveform",
 "oneOf" : [ {
   "$ref" : "#/definitions/Triangular"
 }, {
   "$ref" : "#/definitions/Square"
 } ],
 "definitions" : {
   "Triangular" : {
     "type" : "object",
     "additionalProperties" : false,
     "properties" : {
       "type" : {
          "type" : "string",
          "enum" : [ "TRIANGULAR" ],
          "default" : "TRIANGULAR",
          "description": "This is a triangle"
        }
     },
     "title" : "TRIANGULAR",
     "required" : [ "type" ]
   },
   "Square" : {
     "type" : "object",
     "additionalProperties" : false,
     "properties" : {
       "type" : {
         "type" : "string",
         "enum" : [ "SQUARE" ],
         "default" : "SQUARE",
          "description": "This is a square"
       }
     },
     "title" : "SQUARE",
     "required" : [ "type" ]
   }
 }
}

It's look like it's related to the issue #104 as it's sub-type informations who are missing.

manticorps avatar Dec 09 '19 09:12 manticorps