Skip to content

Commit b82d617

Browse files
authored
filter properties of type class (#1619)
1 parent 26f6bfe commit b82d617

File tree

2 files changed

+101
-10
lines changed

2 files changed

+101
-10
lines changed

openapi/src/main/java/io/micronaut/openapi/visitor/AbstractOpenApiVisitor.java

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
import io.micronaut.inject.ast.GenericPlaceholderElement;
5555
import io.micronaut.inject.ast.MemberElement;
5656
import io.micronaut.inject.ast.PropertyElement;
57+
import io.micronaut.inject.ast.PropertyElementQuery;
5758
import io.micronaut.inject.ast.TypedElement;
5859
import io.micronaut.inject.ast.WildcardElement;
5960
import io.micronaut.inject.visitor.VisitorContext;
@@ -2721,8 +2722,17 @@ private void populateSchemaProperties(OpenAPI openAPI, VisitorContext context, E
27212722
if (classElement != null && !ClassUtils.isJavaLangType(classElement.getName())) {
27222723
List<PropertyElement> beanProperties;
27232724
try {
2724-
beanProperties = classElement.getBeanProperties().stream()
2725-
.filter(p -> !"groovy.lang.MetaClass".equals(p.getType().getName()))
2725+
beanProperties = classElement.getBeanProperties(
2726+
PropertyElementQuery.of(classElement)
2727+
.excludedAnnotations(Set.of(
2728+
Hidden.class.getName(),
2729+
JsonIgnore.class.getName()
2730+
))
2731+
).stream()
2732+
.filter(p ->
2733+
!"groovy.lang.MetaClass".equals(p.getType().getName())
2734+
&& !"java.lang.Class".equals(p.getType().getName())
2735+
)
27262736
.toList();
27272737
} catch (Exception e) {
27282738
warn("Error with getting properties for class " + classElement.getName() + ": " + e + "\n" + Utils.printStackTrace(e), context, classElement);
@@ -2794,14 +2804,7 @@ private void processPropertyElements(OpenAPI openAPI, VisitorContext context, El
27942804
}
27952805

27962806
for (TypedElement publicField : publicFields) {
2797-
boolean isHidden = getAnnotationMetadata(publicField).booleanValue(io.swagger.v3.oas.annotations.media.Schema.class, PROP_HIDDEN).orElse(false);
2798-
var jsonAnySetterAnn = getAnnotation(publicField, JsonAnySetter.class);
2799-
if (isAnnotationPresent(publicField, JsonIgnore.class)
2800-
|| isAnnotationPresent(publicField, Hidden.class)
2801-
|| (jsonAnySetterAnn != null && jsonAnySetterAnn.booleanValue("enabled").orElse(true))
2802-
|| isHidden) {
2803-
continue;
2804-
}
2807+
if (isHiddenElement(publicField)) continue;
28052808

28062809
var isGetterOverridden = false;
28072810
JavadocDescription fieldJavadoc = null;
@@ -2849,6 +2852,17 @@ private void processPropertyElements(OpenAPI openAPI, VisitorContext context, El
28492852
}
28502853
}
28512854

2855+
private static boolean isHiddenElement(TypedElement elementType) {
2856+
boolean isHidden = getAnnotationMetadata(elementType)
2857+
.booleanValue(io.swagger.v3.oas.annotations.media.Schema.class, PROP_HIDDEN).orElse(false);
2858+
var jsonAnySetterAnn = getAnnotation(elementType, JsonAnySetter.class);
2859+
return elementType.getType().isAssignable(Class.class)
2860+
|| isAnnotationPresent(elementType, JsonIgnore.class)
2861+
|| isAnnotationPresent(elementType, Hidden.class)
2862+
|| (jsonAnySetterAnn != null && jsonAnySetterAnn.booleanValue("enabled").orElse(true))
2863+
|| isHidden;
2864+
}
2865+
28522866
private boolean allowedByJsonView(TypedElement publicField, String[] classLvlJsonViewClasses, ClassElement jsonViewClassEl, VisitorContext context) {
28532867
String[] fieldJsonViewClasses = getAnnotationMetadata(publicField).stringValues(JsonView.class);
28542868
if (ArrayUtils.isEmpty(fieldJsonViewClasses)) {
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package io.micronaut.openapi.visitor
2+
3+
import io.micronaut.openapi.AbstractOpenApiTypeElementSpec
4+
import io.swagger.v3.oas.models.OpenAPI
5+
6+
class OpenApiClassPropertySpec extends AbstractOpenApiTypeElementSpec {
7+
void "test class property is not exposed"() {
8+
9+
when:
10+
buildBeanDefinition("test.MyBean", '''
11+
package test;
12+
13+
import io.micronaut.core.annotation.Introspected;
14+
import io.micronaut.http.HttpResponse;
15+
import io.micronaut.http.MediaType;
16+
import io.micronaut.http.annotation.*;
17+
18+
import io.swagger.v3.oas.annotations.Hidden;
19+
import io.swagger.v3.oas.annotations.Operation;
20+
import io.swagger.v3.oas.annotations.Parameter;
21+
import io.swagger.v3.oas.annotations.enums.ParameterIn;
22+
import io.swagger.v3.oas.annotations.media.Content;
23+
import io.swagger.v3.oas.annotations.media.Schema;
24+
import io.swagger.v3.oas.annotations.responses.ApiResponse;
25+
26+
import jakarta.validation.constraints.*;
27+
28+
@Controller
29+
class PersonController {
30+
31+
@Get("/person/{name}")
32+
HttpResponse<Person> get(@NotBlank String name) {
33+
return HttpResponse.ok();
34+
}
35+
}
36+
37+
/**
38+
* The person information.
39+
*/
40+
@Introspected
41+
class Person {
42+
43+
private String name;
44+
private Class<?> personClass;
45+
public String getName() {
46+
return name;
47+
}
48+
public void setName(String name) {
49+
this.name = name;
50+
}
51+
52+
public void setPersonClass(Class<?> personClass) {
53+
this.personClass = personClass;
54+
}
55+
56+
public Class<?> getPersonClass() {
57+
return personClass;
58+
}
59+
}
60+
61+
@jakarta.inject.Singleton
62+
public class MyBean {}
63+
64+
''')
65+
66+
then:
67+
OpenAPI openAPI = Utils.testReference
68+
openAPI?.paths?.get("/person/{name}")?.get
69+
openAPI.components.schemas["Person"]
70+
openAPI.components.schemas["Person"].type == "object"
71+
72+
openAPI.components.schemas["Person"].properties
73+
openAPI.components.schemas["Person"].properties.size() == 1
74+
75+
openAPI.components.schemas["Person"].properties["name"]
76+
}
77+
}

0 commit comments

Comments
 (0)