diff --git a/core/src/main/java/io/smallrye/openapi/runtime/scanner/dataobject/TypeProcessor.java b/core/src/main/java/io/smallrye/openapi/runtime/scanner/dataobject/TypeProcessor.java index 9e79c6064..096aad937 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/scanner/dataobject/TypeProcessor.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/scanner/dataobject/TypeProcessor.java @@ -132,15 +132,17 @@ private Type readArrayType(ArrayType arrayType, Schema arraySchema) { Schema itemSchema = new SchemaImpl(); arraySchema.type(Schema.SchemaType.ARRAY); + Type componentType = typeResolver.resolve(arrayType.component()); + // Only use component (excludes the special name formatting for arrays). - TypeUtil.applyTypeAttributes(arrayType.component(), itemSchema); + TypeUtil.applyTypeAttributes(componentType, itemSchema); // If it's not a terminal type, then push for later inspection. - if (!isTerminalType(arrayType.component()) && index.containsClass(arrayType)) { - pushToStack(arrayType, itemSchema); + if (!isTerminalType(componentType) && index.containsClass(componentType)) { + pushToStack(componentType, itemSchema); } - itemSchema = SchemaRegistry.registerReference(arrayType.component(), typeResolver, itemSchema); + itemSchema = SchemaRegistry.registerReference(componentType, typeResolver, itemSchema); while (arrayType.dimensions() > 1) { Schema parentArrSchema = new SchemaImpl(); @@ -251,7 +253,7 @@ private Schema resolveParameterizedType(Type valueType, Schema schema, Schema pr private Type resolveTypeVariable(Schema schema, Type fieldType, boolean pushToStack) { // Type variable (e.g. A in Foo) - Type resolvedType = typeResolver.getResolvedType(fieldType); + Type resolvedType = typeResolver.resolve(fieldType); DataObjectLogging.logger.resolvedType(fieldType, resolvedType); if (isTerminalType(resolvedType) || !index.containsClass(resolvedType)) { diff --git a/core/src/main/java/io/smallrye/openapi/runtime/scanner/dataobject/TypeResolver.java b/core/src/main/java/io/smallrye/openapi/runtime/scanner/dataobject/TypeResolver.java index 0ab0ab186..93f4a9508 100644 --- a/core/src/main/java/io/smallrye/openapi/runtime/scanner/dataobject/TypeResolver.java +++ b/core/src/main/java/io/smallrye/openapi/runtime/scanner/dataobject/TypeResolver.java @@ -335,7 +335,7 @@ private boolean isExposedByDefault() { * @param fieldType type to resolve * @return resolved type (if found) */ - public Type getResolvedType(Type fieldType) { + private Type getResolvedType(Type fieldType) { Type current = TypeUtil.resolveWildcard(fieldType); for (Map map : resolutionStack) { @@ -373,7 +373,7 @@ private static Type[] resolveArguments(ParameterizedType type, UnaryOperator arg.kind() == Type.Kind.WILDCARD_TYPE)) { return ParameterizedType.create(type.name(), resolveArguments(type, this::resolve), null); } diff --git a/core/src/test/java/io/smallrye/openapi/runtime/scanner/StandaloneSchemaScanTest.java b/core/src/test/java/io/smallrye/openapi/runtime/scanner/StandaloneSchemaScanTest.java index 7c5dd02ba..8b0ef2a8f 100644 --- a/core/src/test/java/io/smallrye/openapi/runtime/scanner/StandaloneSchemaScanTest.java +++ b/core/src/test/java/io/smallrye/openapi/runtime/scanner/StandaloneSchemaScanTest.java @@ -405,13 +405,21 @@ static class MultivaluedMap extends HashMap> { */ @Test void testNestedCustomGenericSchemas() throws IOException, JSONException { - Index index = indexOf(Foo.class, Generic1.class, Generic2.class, CustomMap.class); + Index index = indexOf(Foo.class, Generic0.class, Generic1.class, Generic2.class, CustomMap.class); OpenApiAnnotationScanner scanner = new OpenApiAnnotationScanner(emptyConfig(), index); OpenAPI result = scanner.scan(); printToConsole(result); assertJsonEquals("components.schemas.nested-custom-generics.json", result); } + /* + * Do not annotate with @Schema - test relies on Generic0 registration + * only as an array component of Generic2#arrayOfGeneric0. + */ + static class Generic0 { + T value; + } + static class Generic1 { T value; } @@ -419,6 +427,8 @@ static class Generic1 { static class Generic2 { Generic1 nested; CustomMap nestedMap; + // Do not reference Generic0 other than from this field! + Generic0[] arrayOfGeneric0; } @Schema diff --git a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.nested-custom-generics.json b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.nested-custom-generics.json index cacb3b859..97a2d60af 100644 --- a/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.nested-custom-generics.json +++ b/core/src/test/resources/io/smallrye/openapi/runtime/scanner/components.schemas.nested-custom-generics.json @@ -10,9 +10,23 @@ } } }, + "Generic0String" : { + "type" : "object", + "properties" : { + "value" : { + "type" : "string" + } + } + }, "Generic2String": { "type": "object", "properties": { + "arrayOfGeneric0" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/Generic0String" + } + }, "nested": { "$ref": "#/components/schemas/Generic1String" },