Skip to content

Commit ca3ef4d

Browse files
author
bnasslahsen
committed
Support for Groovy metaclass/metadata. Fixes #509
1 parent 3a46036 commit ca3ef4d

File tree

28 files changed

+304
-49
lines changed

28 files changed

+304
-49
lines changed

springdoc-openapi-common/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,10 @@
4141
<groupId>org.apache.commons</groupId>
4242
<artifactId>commons-lang3</artifactId>
4343
</dependency>
44+
<dependency>
45+
<groupId>org.codehaus.groovy</groupId>
46+
<artifactId>groovy</artifactId>
47+
<optional>true</optional>
48+
</dependency>
4449
</dependencies>
4550
</project>

springdoc-openapi-common/src/main/java/org/springdoc/core/AbstractRequestBuilder.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,9 +257,14 @@ protected boolean isParamToIgnore(MethodParameter parameter) {
257257
return true;
258258
if (parameter.getParameterAnnotation(PathVariable.class) != null || parameter.getParameterAnnotation(RequestParam.class) != null)
259259
return false;
260-
return PARAM_TYPES_TO_IGNORE.stream().anyMatch(paramToIgnore -> paramToIgnore.isAssignableFrom(parameter.getParameterType()));
260+
return isRequestTypeToIgnore(parameter.getParameterType());
261261
}
262262

263+
public static boolean isRequestTypeToIgnore(Class<?> rawClass) {
264+
return PARAM_TYPES_TO_IGNORE.stream().anyMatch(clazz -> clazz.isAssignableFrom(rawClass));
265+
}
266+
267+
263268
private void setParams(Operation operation, List<Parameter> operationParameters, RequestBodyInfo requestBodyInfo) {
264269
if (!CollectionUtils.isEmpty(operationParameters))
265270
operation.setParameters(operationParameters);

springdoc-openapi-common/src/main/java/org/springdoc/core/SpringDocConfiguration.java

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.util.Optional;
2525

2626
import com.fasterxml.jackson.databind.node.ObjectNode;
27+
import groovy.lang.MetaClass;
2728
import io.swagger.v3.core.converter.ModelConverter;
2829
import io.swagger.v3.oas.models.Components;
2930
import io.swagger.v3.oas.models.OpenAPI;
@@ -32,6 +33,7 @@
3233
import org.springdoc.core.converters.AdditionalModelsConverter;
3334
import org.springdoc.core.converters.ModelConverterRegistrar;
3435
import org.springdoc.core.converters.PropertyCustomizingConverter;
36+
import org.springdoc.core.converters.RequestTypeToIgnoreConverter;
3537
import org.springdoc.core.converters.ResponseSupportConverter;
3638
import org.springdoc.core.customizers.OpenApiBuilderCustomiser;
3739
import org.springdoc.core.customizers.OpenApiCustomiser;
@@ -41,6 +43,7 @@
4143
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
4244
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
4345
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
46+
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
4447
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
4548
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
4649
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
@@ -82,56 +85,69 @@ ResponseSupportConverter responseSupportConverter() {
8285
return new ResponseSupportConverter();
8386
}
8487

88+
@ConditionalOnClass(value = { MetaClass.class })
89+
class GroovyProvider {
90+
@Bean
91+
Object ignoreGroovyMetaClass () {
92+
SpringDocUtils.getConfig().addRequestWrapperToIgnore(MetaClass.class);
93+
return null;
94+
}
95+
@Bean
96+
RequestTypeToIgnoreConverter requestTypeToIgnoreConverter() {
97+
return new RequestTypeToIgnoreConverter();
98+
}
99+
}
100+
85101
@Bean
86-
public OpenAPIBuilder openAPIBuilder(Optional<OpenAPI> openAPI, ApplicationContext context,
102+
OpenAPIBuilder openAPIBuilder(Optional<OpenAPI> openAPI, ApplicationContext context,
87103
SecurityParser securityParser,
88104
SpringDocConfigProperties springDocConfigProperties,
89105
Optional<List<OpenApiBuilderCustomiser>> openApiBuilderCustomisers) {
90106
return new OpenAPIBuilder(openAPI, context, securityParser, springDocConfigProperties, openApiBuilderCustomisers);
91107
}
92108

93109
@Bean
94-
public ModelConverterRegistrar modelConverterRegistrar(Optional<List<ModelConverter>> modelConverters) {
110+
ModelConverterRegistrar modelConverterRegistrar(Optional<List<ModelConverter>> modelConverters) {
95111
return new ModelConverterRegistrar(modelConverters.orElse(Collections.emptyList()));
96112
}
97113

98114
@Bean
99115
@ConditionalOnWebApplication
100-
public OperationBuilder operationBuilder(GenericParameterBuilder parameterBuilder, RequestBodyBuilder requestBodyBuilder,
116+
OperationBuilder operationBuilder(GenericParameterBuilder parameterBuilder, RequestBodyBuilder requestBodyBuilder,
101117
SecurityParser securityParser, PropertyResolverUtils propertyResolverUtils) {
102118
return new OperationBuilder(parameterBuilder, requestBodyBuilder,
103119
securityParser, propertyResolverUtils);
104120
}
105121

106122
@Bean
107-
public PropertyResolverUtils propertyResolverUtils(ConfigurableBeanFactory factory) {
123+
PropertyResolverUtils propertyResolverUtils(ConfigurableBeanFactory factory) {
108124
return new PropertyResolverUtils(factory);
109125
}
110126

111127
@Bean
112128
@ConditionalOnWebApplication
113-
public RequestBodyBuilder requestBodyBuilder(GenericParameterBuilder parameterBuilder) {
129+
RequestBodyBuilder requestBodyBuilder(GenericParameterBuilder parameterBuilder) {
114130
return new RequestBodyBuilder(parameterBuilder);
115131
}
116132

117133
@Bean
118-
public SecurityParser securityParser(PropertyResolverUtils propertyResolverUtils) {
134+
SecurityParser securityParser(PropertyResolverUtils propertyResolverUtils) {
119135
return new SecurityParser(propertyResolverUtils);
120136
}
121137

122138
@Bean
123-
public ReturnTypeParser genericReturnTypeParser() {
139+
ReturnTypeParser genericReturnTypeParser() {
124140
return new ReturnTypeParser() {};
125141
}
126142

127143
@Bean
128-
public GenericParameterBuilder parameterBuilder(PropertyResolverUtils propertyResolverUtils) {
144+
GenericParameterBuilder parameterBuilder(PropertyResolverUtils propertyResolverUtils) {
129145
return new GenericParameterBuilder(propertyResolverUtils);
130146
}
131147

132148
@Bean
133149
@ConditionalOnProperty(SPRINGDOC_SCHEMA_RESOLVE_PROPERTIES)
134-
public OpenApiCustomiser propertiesResolverForSchema(PropertyResolverUtils propertyResolverUtils, OpenAPIBuilder openAPIBuilder) {
150+
OpenApiCustomiser propertiesResolverForSchema(PropertyResolverUtils propertyResolverUtils, OpenAPIBuilder openAPIBuilder) {
135151
return openApi -> {
136152
Components components = openApi.getComponents();
137153
Map<String, Schema> schemas = components.getSchemas();
@@ -147,14 +163,14 @@ static class ConditionOnCacheOrGroupedOpenApi extends AnyNestedCondition {
147163

148164
@Bean
149165
@ConditionalOnBean(GroupedOpenApi.class)
150-
public BeanFactoryPostProcessor beanFactoryPostProcessor1() {
166+
BeanFactoryPostProcessor beanFactoryPostProcessor1() {
151167
return getBeanFactoryPostProcessor();
152168
}
153169

154170
@Bean
155171
@ConditionalOnProperty(name = SPRINGDOC_CACHE_DISABLED)
156172
@ConditionalOnMissingBean(GroupedOpenApi.class)
157-
public BeanFactoryPostProcessor beanFactoryPostProcessor2() {
173+
BeanFactoryPostProcessor beanFactoryPostProcessor2() {
158174
return getBeanFactoryPostProcessor();
159175
}
160176

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package org.springdoc.core.converters;
2+
3+
import java.util.Iterator;
4+
5+
import com.fasterxml.jackson.databind.JavaType;
6+
import io.swagger.v3.core.converter.AnnotatedType;
7+
import io.swagger.v3.core.converter.ModelConverter;
8+
import io.swagger.v3.core.converter.ModelConverterContext;
9+
import io.swagger.v3.core.util.Json;
10+
import io.swagger.v3.oas.models.media.Schema;
11+
import org.springdoc.core.AbstractRequestBuilder;
12+
13+
public class RequestTypeToIgnoreConverter implements ModelConverter {
14+
15+
@Override
16+
public Schema resolve(AnnotatedType type, ModelConverterContext context, Iterator<ModelConverter> chain) {
17+
if (type.isSchemaProperty()) {
18+
JavaType javaType = Json.mapper().constructType(type.getType());
19+
if (type != null) {
20+
Class<?> cls = javaType.getRawClass();
21+
if(AbstractRequestBuilder.isRequestTypeToIgnore(cls))
22+
return null;
23+
}
24+
}
25+
return (chain.hasNext()) ? chain.next().resolve(type, context, chain) : null;
26+
}
27+
}

springdoc-openapi-data-rest/src/main/java/org/springdoc/core/SpringDocDataRestConfiguration.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,11 @@ public class SpringDocDataRestConfiguration {
5757
.replaceWithClass(org.springframework.data.domain.PageRequest.class, Pageable.class);
5858
}
5959

60-
@Configuration
6160
@ConditionalOnClass(value = { QuerydslBindingsFactory.class })
6261
class QuerydslProvider {
6362

6463
@Bean
65-
public QuerydslPredicateOperationCustomizer queryDslQuerydslPredicateOperationCustomizer(Optional<QuerydslBindingsFactory> querydslBindingsFactory) {
64+
QuerydslPredicateOperationCustomizer queryDslQuerydslPredicateOperationCustomizer(Optional<QuerydslBindingsFactory> querydslBindingsFactory) {
6665
if (querydslBindingsFactory.isPresent()) {
6766
getConfig().addRequestWrapperToIgnore(Predicate.class);
6867
return new QuerydslPredicateOperationCustomizer(querydslBindingsFactory.get());
@@ -71,12 +70,11 @@ public QuerydslPredicateOperationCustomizer queryDslQuerydslPredicateOperationCu
7170
}
7271
}
7372

74-
@Configuration
7573
@ConditionalOnClass(RepositoryRestConfiguration.class)
7674
class HalProviderConfiguration {
7775

7876
@Bean
79-
public HalProvider halProvider(Optional<RepositoryRestConfiguration> repositoryRestConfiguration) {
77+
HalProvider halProvider(Optional<RepositoryRestConfiguration> repositoryRestConfiguration) {
8078
return repositoryRestConfiguration.isPresent() ? new HalProvider(repositoryRestConfiguration.get()) : null;
8179
}
8280

@@ -87,7 +85,7 @@ public HalProvider halProvider(Optional<RepositoryRestConfiguration> repositoryR
8785
* @see org.springframework.hateoas.mediatype.hal.Jackson2HalModule.HalLinkListSerializer#serialize(Links, JsonGenerator, SerializerProvider)
8886
*/
8987
@Bean
90-
public OpenApiCustomiser linksSchemaCustomiser(Optional<RepositoryRestConfiguration> repositoryRestConfiguration) {
88+
OpenApiCustomiser linksSchemaCustomiser(Optional<RepositoryRestConfiguration> repositoryRestConfiguration) {
9189
if (!repositoryRestConfiguration.isPresent() || !repositoryRestConfiguration.get().useHalAsDefaultJsonMediaType()) {
9290
return openApi -> {
9391
};

springdoc-openapi-data-rest/src/main/java/org/springdoc/core/converters/Pageable.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,17 @@
1818

1919
package org.springdoc.core.converters;
2020

21-
import io.swagger.v3.oas.annotations.media.ArraySchema;
22-
import io.swagger.v3.oas.annotations.media.Schema;
23-
import org.springframework.lang.Nullable;
21+
import java.util.List;
22+
import java.util.Objects;
2423

2524
import javax.validation.constraints.Max;
2625
import javax.validation.constraints.Min;
2726
import javax.validation.constraints.NotNull;
28-
import java.util.List;
29-
import java.util.Objects;
27+
28+
import io.swagger.v3.oas.annotations.media.ArraySchema;
29+
import io.swagger.v3.oas.annotations.media.Schema;
30+
31+
import org.springframework.lang.Nullable;
3032

3133
@NotNull
3234
public class Pageable {

springdoc-openapi-data-rest/src/main/java/org/springdoc/core/converters/PageableAsQueryParam.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,17 @@
1818

1919
package org.springdoc.core.converters;
2020

21+
import java.lang.annotation.ElementType;
22+
import java.lang.annotation.Retention;
23+
import java.lang.annotation.RetentionPolicy;
24+
import java.lang.annotation.Target;
25+
2126
import io.swagger.v3.oas.annotations.Parameter;
2227
import io.swagger.v3.oas.annotations.enums.ParameterIn;
2328
import io.swagger.v3.oas.annotations.media.ArraySchema;
2429
import io.swagger.v3.oas.annotations.media.Content;
2530
import io.swagger.v3.oas.annotations.media.Schema;
2631

27-
import java.lang.annotation.ElementType;
28-
import java.lang.annotation.Retention;
29-
import java.lang.annotation.RetentionPolicy;
30-
import java.lang.annotation.Target;
31-
3232
/**
3333
* @deprecated Use {@link org.springdoc.api.annotations.ParameterObject} annotation
3434
* on {@link org.springframework.data.domain.Pageable} method parameter instead.

springdoc-openapi-data-rest/src/test/java/test/org/springdoc/api/app7/HelloController.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,17 @@
1818

1919
package test.org.springdoc.api.app7;
2020

21+
import java.util.List;
22+
23+
import javax.validation.constraints.NotNull;
24+
2125
import org.springdoc.api.annotations.ParameterObject;
26+
2227
import org.springframework.data.domain.Pageable;
2328
import org.springframework.http.ResponseEntity;
2429
import org.springframework.web.bind.annotation.GetMapping;
2530
import org.springframework.web.bind.annotation.RestController;
2631

27-
import javax.validation.constraints.NotNull;
28-
import java.util.List;
29-
3032
@RestController
3133
public class HelloController {
3234

springdoc-openapi-data-rest/src/test/java/test/org/springdoc/api/app7/SpringDocApp7Test.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@
1818

1919
package test.org.springdoc.api.app7;
2020

21-
import org.springframework.boot.autoconfigure.SpringBootApplication;
2221
import test.org.springdoc.api.AbstractSpringDocTest;
2322

23+
import org.springframework.boot.autoconfigure.SpringBootApplication;
24+
2425
public class SpringDocApp7Test extends AbstractSpringDocTest {
2526

2627
@SpringBootApplication

springdoc-openapi-security/src/main/java/org/springdoc/core/SpringDocSecurityConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public class SpringDocSecurityConfiguration {
4343
@ConditionalOnBean(FrameworkEndpointHandlerMapping.class)
4444
class SpringSecurityOAuth2ProviderConfiguration {
4545
@Bean
46-
public SpringSecurityOAuth2Provider springSecurityOAuth2Provider(FrameworkEndpointHandlerMapping oauth2EndpointHandlerMapping) {
46+
SpringSecurityOAuth2Provider springSecurityOAuth2Provider(FrameworkEndpointHandlerMapping oauth2EndpointHandlerMapping) {
4747
return new SpringSecurityOAuth2Provider(oauth2EndpointHandlerMapping);
4848
}
4949
}

0 commit comments

Comments
 (0)