Skip to content

Commit

Permalink
Merge pull request #1133 from altro3/fix_wildcards_4.10
Browse files Browse the repository at this point in the history
Add process WildcardElement and GenericPlaceholderElement (4.10)
  • Loading branch information
altro3 authored Jul 16, 2023
2 parents cc796ab + 201c3bc commit 583fabc
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
import io.micronaut.inject.ast.MemberElement;
import io.micronaut.inject.ast.PropertyElement;
import io.micronaut.inject.ast.TypedElement;
import io.micronaut.inject.ast.WildcardElement;
import io.micronaut.inject.visitor.VisitorContext;
import io.micronaut.openapi.javadoc.JavadocDescription;
import io.micronaut.openapi.swagger.PrimitiveType;
Expand Down Expand Up @@ -787,13 +788,28 @@ protected Schema resolveSchema(OpenAPI openAPI, @Nullable Element definingElemen
}
}

ClassElement componentType = type.getFirstTypeArgument().orElse(null);
Map<String, ClassElement> typeArgs = type.getTypeArguments();
Boolean isArray = null;
Boolean isIterable = null;

ClassElement componentType = type != null ? type.getFirstTypeArgument().orElse(null) : null;
if (type instanceof WildcardElement) {
WildcardElement wildcardEl = (WildcardElement) type;
type = CollectionUtils.isNotEmpty(wildcardEl.getUpperBounds()) ? wildcardEl.getUpperBounds().get(0) : null;
} else if (type instanceof GenericPlaceholderElement) {
GenericPlaceholderElement placeholderEl = (GenericPlaceholderElement) type;
isArray = type.isArray();
isIterable = type.isIterable();
type = CollectionUtils.isNotEmpty(placeholderEl.getBounds()) ? placeholderEl.getBounds().get(0) : null;
}
Map<String, ClassElement> typeArgs = type != null ? type.getTypeArguments() : null;

Schema schema = null;

if (type instanceof EnumElement) {
schema = getSchemaDefinition(openAPI, context, type, typeArgs, definingElement, mediaTypes, jsonViewClass);
if (isArray != null && isArray) {
schema = SchemaUtils.arraySchema(schema);
}
} else {

boolean isPublisher = false;
Expand Down Expand Up @@ -830,6 +846,13 @@ protected Schema resolveSchema(OpenAPI openAPI, @Nullable Element definingElemen

if (type != null) {

if (isArray == null) {
isArray = type.isArray();
}
if (isIterable == null) {
isIterable = type.isIterable();
}

String typeName = type.getName();
ClassElement customTypeSchema = OpenApiApplicationVisitor.getCustomSchema(typeName, typeArgs, context);
if (customTypeSchema != null) {
Expand All @@ -843,13 +866,13 @@ protected Schema resolveSchema(OpenAPI openAPI, @Nullable Element definingElemen
typeName = PrimitiveType.BINARY.name();
}
PrimitiveType primitiveType = PrimitiveType.fromName(typeName);
if (!type.isArray() && ClassUtils.isJavaLangType(typeName)) {
if (!isArray && ClassUtils.isJavaLangType(typeName)) {
schema = getPrimitiveType(typeName);
} else if (!type.isArray() && primitiveType != null) {
} else if (!isArray && primitiveType != null) {
schema = primitiveType.createProperty();
} else if (type.isAssignable(Map.class.getName())) {
schema = new MapSchema();
if (typeArgs.isEmpty()) {
if (CollectionUtils.isEmpty(typeArgs)) {
schema.setAdditionalProperties(true);
} else {
ClassElement valueType = typeArgs.get("V");
Expand All @@ -859,8 +882,8 @@ protected Schema resolveSchema(OpenAPI openAPI, @Nullable Element definingElemen
schema.setAdditionalProperties(resolveSchema(openAPI, type, valueType, context, mediaTypes, jsonViewClass, null, classJavadoc));
}
}
} else if (type.isIterable()) {
if (type.isArray()) {
} else if (isIterable) {
if (isArray) {
schema = resolveSchema(openAPI, type, type.fromArray(), context, mediaTypes, jsonViewClass, null, classJavadoc);
if (schema != null) {
schema = SchemaUtils.arraySchema(schema);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -486,4 +486,65 @@ class MyBean {}
openAPI.components.schemas['TimeUnit'].enum[5] == 'Week'
openAPI.components.schemas['Time'].allOf[0].$ref == '#/components/schemas/Quantity_Time.TimeUnit_'
}


void "test schema with generic wildcard or placeholder"() {
given:
buildBeanDefinition('test.MyBean', '''
package test;
import java.util.Collection;
import io.micronaut.core.annotation.Introspected;
import io.micronaut.core.annotation.Nullable;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.annotation.QueryValue;
@Controller
class CommonController {
@Get("/get1")
public <T extends Channel> String index1(@Nullable @QueryValue T[] channels) {
return null;
}
@Get("/get2")
public String index2(@Nullable @QueryValue Collection<? extends Channel> channels) {
return null;
}
@Introspected
enum Channel {
SYSTEM1,
SYSTEM2
}
}
@jakarta.inject.Singleton
class MyBean {}
''')

OpenAPI openAPI = Utils.testReference
Operation get1 = openAPI.paths?.get("/get1")?.get
Operation get2 = openAPI.paths?.get("/get2")?.get

expect:
get1
get1.parameters.get(0).name == 'channels'
get1.parameters.get(0).in == 'query'
get1.parameters.get(0).schema
get1.parameters.get(0).schema.type == 'array'
get1.parameters.get(0).schema.nullable
get1.parameters.get(0).schema.items.$ref == '#/components/schemas/CommonController.Channel'

get2
get2.parameters.get(0).name == 'channels'
get2.parameters.get(0).in == 'query'
get2.parameters.get(0).schema
get2.parameters.get(0).schema.type == 'array'
get2.parameters.get(0).schema.nullable
get2.parameters.get(0).schema.items.$ref == '#/components/schemas/CommonController.Channel'
}
}

0 comments on commit 583fabc

Please sign in to comment.