diff --git a/openapi-generator-for-spring-common/src/main/java/de/qaware/openapigeneratorforspring/common/schema/resolver/type/extension/jackson/TypeResolverForJacksonPolymorphism.java b/openapi-generator-for-spring-common/src/main/java/de/qaware/openapigeneratorforspring/common/schema/resolver/type/extension/jackson/TypeResolverForJacksonPolymorphism.java index d47cee90..23c71713 100644 --- a/openapi-generator-for-spring-common/src/main/java/de/qaware/openapigeneratorforspring/common/schema/resolver/type/extension/jackson/TypeResolverForJacksonPolymorphism.java +++ b/openapi-generator-for-spring-common/src/main/java/de/qaware/openapigeneratorforspring/common/schema/resolver/type/extension/jackson/TypeResolverForJacksonPolymorphism.java @@ -111,6 +111,11 @@ public RecursionKey resolve( if (jsonTypeInfo == null) { return null; } + JsonTypeInfo.As includeAs = jsonTypeInfo.include(); + if (includeAs != JsonTypeInfo.As.PROPERTY && includeAs != JsonTypeInfo.As.EXISTING_PROPERTY) { + LOGGER.warn("Encountered unsupported JsonTypeInfo annotation with include = {}, will ignore", jsonTypeInfo.include()); + return null; + } String propertyName = findPropertyName(jsonTypeInfo); Class classOwningJsonTypeInfo = findClassOwningJsonTypeInfo(initialType.getType().getRawClass()) @@ -140,7 +145,7 @@ public RecursionKey resolve( jsonSubTypes.forEach((typeName, type) -> schemaBuilderFromType.buildSchemaReferenceFromType( objectMapper.constructType(type), - createAnnotationsSupplier(type, propertyName, jsonSubTypes.keySet(), propertySchemaName), + createAnnotationsSupplier(type, propertyName, jsonSubTypes.keySet(), propertySchemaName, includeAs), schemaReference -> { schemaReferenceMapping.put(typeName, schemaReference.getRef()); oneOfSchemas.set(oneOfSchemasIndexMap.get(typeName), schemaReference); @@ -160,7 +165,9 @@ public RecursionKey resolve( @Override public Map findProperties(SchemaResolver.Caller caller, JavaType javaType, AnnotationsSupplier annotationsSupplier) { - return annotationsSupplier.findAnnotations(PropertyNameAnnotation.class) + return annotationsSupplier.findAnnotations(PropertyIncludeAsAnnotation.class) + .filter(a -> a.value() == JsonTypeInfo.As.PROPERTY) + .flatMap(ignored -> annotationsSupplier.findAnnotations(PropertyNameAnnotation.class)) .findFirst() .map(propertyNameAnnotation -> Collections.singletonMap( propertyNameAnnotation.value(), new SchemaProperty() { @@ -199,7 +206,8 @@ public void customize(Schema schema, JavaType javaType, AnnotationsSupplier anno if (!propertySchemaName.isPresent()) { return; } - properties.get(propertyName.get()).customize( + SchemaPropertyCallback schemaPropertyCallback = properties.get(propertyName.get()); + schemaPropertyCallback.customize( (propertySchema, propertyJavaType, propertyAnnotationsSupplier) -> { propertySchema.setName(propertySchemaName.get()); propertySchema.setEnumValues(propertyEnumValues.get()); @@ -215,7 +223,7 @@ private JsonTypeInfo getJsonTypeInfo(Schema schema) { return null; } - private AnnotationsSupplier createAnnotationsSupplier(Class type, String propertyName, Collection propertyEnumValues, String propertySchemaName) { + private AnnotationsSupplier createAnnotationsSupplier(Class type, String propertyName, Collection propertyEnumValues, String propertySchemaName, JsonTypeInfo.As includeAs) { AnnotationsSupplier annotationsSupplier = annotationsSupplierFactory.createFromAnnotatedElement(type); return new AnnotationsSupplier() { @Override @@ -230,6 +238,8 @@ public Stream findAnnotations(Class annotationType) return Stream.of(annotationType.cast(PropertyEnumValuesAnnotation.FACTORY.apply(propertyEnumValues.toArray(new String[0])))); } else if (PropertySchemaNameAnnotation.class.equals(annotationType)) { return Stream.of(annotationType.cast(PropertySchemaNameAnnotation.FACTORY.apply(propertySchemaName))); + } else if (PropertyIncludeAsAnnotation.class.equals(annotationType)) { + return Stream.of(annotationType.cast(PropertyIncludeAsAnnotation.FACTORY.apply(includeAs))); } return annotationsSupplier.findAnnotations(annotationType); } @@ -312,6 +322,12 @@ public JacksonPolymorphismSchema(String name, JsonTypeInfo jsonTypeInfo) { String value(); } + private @interface PropertyIncludeAsAnnotation { + Function FACTORY = createAnnotationProxyWithValueFactory(PropertyIncludeAsAnnotation.class, JsonTypeInfo.As.class); + + JsonTypeInfo.As value(); + } + @Override public int getOrder() { return ORDER; diff --git a/openapi-generator-for-spring-test/src/test/java/de/qaware/openapigeneratorforspring/test/app54/App54Controller.java b/openapi-generator-for-spring-test/src/test/java/de/qaware/openapigeneratorforspring/test/app54/App54Controller.java index 415ab3b6..b3b5309a 100644 --- a/openapi-generator-for-spring-test/src/test/java/de/qaware/openapigeneratorforspring/test/app54/App54Controller.java +++ b/openapi-generator-for-spring-test/src/test/java/de/qaware/openapigeneratorforspring/test/app54/App54Controller.java @@ -2,7 +2,9 @@ import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import lombok.Value; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -15,22 +17,26 @@ public Animal mapping1() { return null; } - @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") + @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "type") @JsonSubTypes({ @JsonSubTypes.Type(value = Dog.class, name = "DOG"), @JsonSubTypes.Type(value = Cat.class, name = "CAT"), }) - private interface Animal { - + @RequiredArgsConstructor(access = AccessLevel.PROTECTED) + @Getter + private abstract static class Animal { + private final String type; } - @Value - private static class Dog { - String wuff; + private static class Dog extends Animal { + private Dog() { + super("DOG"); + } } - @Value - private static class Cat { - String meow; + private static class Cat extends Animal { + private Cat() { + super("CAT"); + } } } diff --git a/openapi-generator-for-spring-test/src/test/resources/openApiJson/app54.json b/openapi-generator-for-spring-test/src/test/resources/openApiJson/app54.json index 161f847d..ac1152cb 100644 --- a/openapi-generator-for-spring-test/src/test/resources/openApiJson/app54.json +++ b/openapi-generator-for-spring-test/src/test/resources/openApiJson/app54.json @@ -37,9 +37,6 @@ "properties": { "type": { "$ref": "#/components/schemas/App54Controller.AnimalType" - }, - "wuff": { - "type": "string" } } }, @@ -48,9 +45,6 @@ "properties": { "type": { "$ref": "#/components/schemas/App54Controller.AnimalType" - }, - "meow": { - "type": "string" } } }, @@ -73,4 +67,4 @@ } } } -} +} \ No newline at end of file