Skip to content

Commit 7413f89

Browse files
committed
Add Native Support
1 parent 6ee2833 commit 7413f89

File tree

10 files changed

+341
-18
lines changed

10 files changed

+341
-18
lines changed

springdoc-openapi-starter-common/pom.xml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
1+
<project xmlns="http://maven.apache.org/POM/4.0.0"
2+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
24
<modelVersion>4.0.0</modelVersion>
35
<parent>
46
<groupId>org.springdoc</groupId>
@@ -83,6 +85,12 @@
8385
<artifactId>querydsl-core</artifactId>
8486
<optional>true</optional>
8587
</dependency>
88+
<!-- classgraph -->
89+
<dependency>
90+
<groupId>io.github.classgraph</groupId>
91+
<artifactId>classgraph</artifactId>
92+
<optional>true</optional>
93+
</dependency>
8694
</dependencies>
8795
<build>
8896
<resources>

springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocDataRestConfiguration.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
import com.fasterxml.jackson.databind.ObjectMapper;
3030
import com.querydsl.core.types.Predicate;
31+
import org.springdoc.core.configuration.hints.SpringDocDataRestHints;
3132
import org.springdoc.core.converters.models.DefaultPageable;
3233
import org.springdoc.core.customizers.QuerydslPredicateOperationCustomizer;
3334
import org.springdoc.core.data.DataRestOperationService;
@@ -56,6 +57,7 @@
5657
import org.springframework.context.ApplicationContext;
5758
import org.springframework.context.annotation.Bean;
5859
import org.springframework.context.annotation.Configuration;
60+
import org.springframework.context.annotation.ImportRuntimeHints;
5961
import org.springframework.context.annotation.Lazy;
6062
import org.springframework.context.annotation.Primary;
6163
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
@@ -85,6 +87,7 @@
8587
@ConditionalOnClass(RepositoryRestConfiguration.class)
8688
@ConditionalOnWebApplication
8789
@ConditionalOnBean(SpringDocConfiguration.class)
90+
@ImportRuntimeHints(SpringDocDataRestHints.class)
8891
public class SpringDocDataRestConfiguration {
8992

9093
/**

springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocHints.java renamed to springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocNativeConfiguration.java

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,42 +29,29 @@
2929
import java.util.Properties;
3030

3131
import org.apache.commons.lang3.StringUtils;
32-
import org.springdoc.core.configuration.SpringDocHints.SpringDocRuntimeHints;
3332
import org.springdoc.core.properties.SwaggerUiConfigProperties;
3433

35-
import org.springframework.aot.hint.RuntimeHints;
36-
import org.springframework.aot.hint.RuntimeHintsRegistrar;
3734
import org.springframework.beans.factory.InitializingBean;
3835
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
3936
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
4037
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
4138
import org.springframework.context.annotation.Configuration;
42-
import org.springframework.context.annotation.ImportRuntimeHints;
4339
import org.springframework.context.annotation.Lazy;
4440
import org.springframework.core.io.ClassPathResource;
4541
import org.springframework.core.io.Resource;
4642
import org.springframework.core.io.support.PropertiesLoaderUtils;
4743
import org.springframework.util.AntPathMatcher;
4844

4945
/**
50-
* The type Spring doc hints.
46+
* The type Spring doc Native Configuration.
5147
* @author bnasslahsen
5248
*/
5349
@Lazy(false)
5450
@ConditionalOnExpression("${springdoc.api-docs.enabled:true} and ${springdoc.enable-native-support:false}")
5551
@ConditionalOnWebApplication
5652
@Configuration(proxyBeanMethods = false)
5753
@ConditionalOnBean(SpringDocConfiguration.class)
58-
@ImportRuntimeHints(SpringDocRuntimeHints.class)
59-
public class SpringDocHints implements InitializingBean {
60-
61-
static class SpringDocRuntimeHints implements RuntimeHintsRegistrar {
62-
@Override
63-
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
64-
hints.resources().registerPattern(SpringDocHints.SPRINGDOC_CONFIG_PROPERTIES)
65-
.registerResourceBundle("sun.util.resources.LocaleNames");
66-
}
67-
}
54+
public class SpringDocNativeConfiguration implements InitializingBean {
6855

6956
/**
7057
* The Swagger ui config properties.
@@ -86,7 +73,7 @@ public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
8673
*
8774
* @param optionalSwaggerUiConfigProperties the swagger ui config properties
8875
*/
89-
public SpringDocHints(Optional<SwaggerUiConfigProperties> optionalSwaggerUiConfigProperties) {
76+
public SpringDocNativeConfiguration(Optional<SwaggerUiConfigProperties> optionalSwaggerUiConfigProperties) {
9077
this.optionalSwaggerUiConfigProperties = optionalSwaggerUiConfigProperties;
9178
}
9279

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
*
3+
* *
4+
* * *
5+
* * * *
6+
* * * * * Copyright 2019-2022 the original author or authors.
7+
* * * * *
8+
* * * * * Licensed under the Apache License, Version 2.0 (the "License");
9+
* * * * * you may not use this file except in compliance with the License.
10+
* * * * * You may obtain a copy of the License at
11+
* * * * *
12+
* * * * * https://www.apache.org/licenses/LICENSE-2.0
13+
* * * * *
14+
* * * * * Unless required by applicable law or agreed to in writing, software
15+
* * * * * distributed under the License is distributed on an "AS IS" BASIS,
16+
* * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
* * * * * See the License for the specific language governing permissions and
18+
* * * * * limitations under the License.
19+
* * * *
20+
* * *
21+
* *
22+
*
23+
*/
24+
25+
package org.springdoc.core.configuration.hints;
26+
27+
import java.util.Arrays;
28+
29+
import org.apache.commons.lang3.reflect.FieldUtils;
30+
import org.springdoc.core.extractor.DelegatingMethodParameter;
31+
32+
import org.springframework.aot.hint.MemberCategory;
33+
import org.springframework.aot.hint.RuntimeHints;
34+
import org.springframework.aot.hint.RuntimeHintsRegistrar;
35+
import org.springframework.data.rest.core.mapping.TypedResourceDescription;
36+
37+
/**
38+
* The type Spring doc DataRest hints.
39+
* @author bnasslahsen
40+
*/
41+
public class SpringDocDataRestHints implements RuntimeHintsRegistrar {
42+
43+
//spring-data-rest
44+
static String[] springDataRestTypeNames = { "org.springframework.data.rest.webmvc.config.DelegatingHandlerMapping",
45+
"org.springframework.data.rest.webmvc.support.DelegatingHandlerMapping",
46+
"org.springframework.data.rest.webmvc.RepositoryPropertyReferenceController",
47+
"org.springframework.data.rest.webmvc.RepositorySearchController",
48+
"org.springframework.data.rest.webmvc.RepositorySchemaController",
49+
"org.springframework.data.rest.webmvc.RepositoryEntityController",
50+
"org.springdoc.webflux.core.fn.SpringdocRouteBuilder",
51+
"org.springdoc.webflux.core.visitor.RouterFunctionVisitor"
52+
};
53+
54+
@Override
55+
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
56+
//springdoc
57+
hints.reflection().registerField(
58+
FieldUtils.getField(TypedResourceDescription.class, "type", true));
59+
hints.reflection().registerField(
60+
FieldUtils.getDeclaredField(DelegatingMethodParameter.class, "additionalParameterAnnotations", true));
61+
62+
//spring-data-rest
63+
Arrays.stream(springDataRestTypeNames).forEach(springDataRestTypeName ->
64+
hints.reflection()
65+
.registerTypeIfPresent(classLoader, springDataRestTypeName,
66+
(hint) -> hint.withMembers(MemberCategory.DECLARED_FIELDS,
67+
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
68+
MemberCategory.INVOKE_DECLARED_METHODS
69+
))
70+
);
71+
72+
hints.reflection()
73+
.registerType(java.lang.Module.class,
74+
(hint) -> hint.withMembers(MemberCategory.DECLARED_FIELDS,
75+
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
76+
MemberCategory.INVOKE_DECLARED_METHODS));
77+
}
78+
79+
}
80+
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
/*
2+
*
3+
* *
4+
* * *
5+
* * * *
6+
* * * * * Copyright 2019-2022 the original author or authors.
7+
* * * * *
8+
* * * * * Licensed under the Apache License, Version 2.0 (the "License");
9+
* * * * * you may not use this file except in compliance with the License.
10+
* * * * * You may obtain a copy of the License at
11+
* * * * *
12+
* * * * * https://www.apache.org/licenses/LICENSE-2.0
13+
* * * * *
14+
* * * * * Unless required by applicable law or agreed to in writing, software
15+
* * * * * distributed under the License is distributed on an "AS IS" BASIS,
16+
* * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
* * * * * See the License for the specific language governing permissions and
18+
* * * * * limitations under the License.
19+
* * * *
20+
* * *
21+
* *
22+
*
23+
*/
24+
25+
package org.springdoc.core.configuration.hints;
26+
27+
import java.util.Arrays;
28+
29+
import io.swagger.v3.core.converter.ModelConverter;
30+
import io.swagger.v3.core.filter.SpecFilter;
31+
import io.swagger.v3.core.jackson.ApiResponsesSerializer;
32+
import io.swagger.v3.core.jackson.PathsSerializer;
33+
import io.swagger.v3.core.jackson.mixin.Components31Mixin;
34+
import io.swagger.v3.core.jackson.mixin.ComponentsMixin;
35+
import io.swagger.v3.core.jackson.mixin.DateSchemaMixin;
36+
import io.swagger.v3.core.jackson.mixin.Discriminator31Mixin;
37+
import io.swagger.v3.core.jackson.mixin.ExampleMixin;
38+
import io.swagger.v3.core.jackson.mixin.ExtensionsMixin;
39+
import io.swagger.v3.core.jackson.mixin.MediaTypeMixin;
40+
import io.swagger.v3.core.jackson.mixin.OpenAPI31Mixin;
41+
import io.swagger.v3.core.jackson.mixin.OpenAPIMixin;
42+
import io.swagger.v3.core.jackson.mixin.OperationMixin;
43+
import io.swagger.v3.core.jackson.mixin.Schema31Mixin;
44+
import io.swagger.v3.core.jackson.mixin.SchemaMixin;
45+
import io.swagger.v3.oas.models.Components;
46+
import io.swagger.v3.oas.models.OpenAPI;
47+
import io.swagger.v3.oas.models.PathItem;
48+
import io.swagger.v3.oas.models.Paths;
49+
import io.swagger.v3.oas.models.examples.Example;
50+
import io.swagger.v3.oas.models.media.BinarySchema;
51+
import io.swagger.v3.oas.models.media.BooleanSchema;
52+
import io.swagger.v3.oas.models.media.ByteArraySchema;
53+
import io.swagger.v3.oas.models.media.ComposedSchema;
54+
import io.swagger.v3.oas.models.media.DateSchema;
55+
import io.swagger.v3.oas.models.media.DateTimeSchema;
56+
import io.swagger.v3.oas.models.media.Discriminator;
57+
import io.swagger.v3.oas.models.media.EmailSchema;
58+
import io.swagger.v3.oas.models.media.EncodingProperty;
59+
import io.swagger.v3.oas.models.media.FileSchema;
60+
import io.swagger.v3.oas.models.media.IntegerSchema;
61+
import io.swagger.v3.oas.models.media.MapSchema;
62+
import io.swagger.v3.oas.models.media.MediaType;
63+
import io.swagger.v3.oas.models.media.NumberSchema;
64+
import io.swagger.v3.oas.models.media.ObjectSchema;
65+
import io.swagger.v3.oas.models.media.PasswordSchema;
66+
import io.swagger.v3.oas.models.media.StringSchema;
67+
import io.swagger.v3.oas.models.media.UUIDSchema;
68+
import io.swagger.v3.oas.models.media.XML;
69+
import io.swagger.v3.oas.models.parameters.CookieParameter;
70+
import io.swagger.v3.oas.models.parameters.HeaderParameter;
71+
import io.swagger.v3.oas.models.parameters.PathParameter;
72+
import io.swagger.v3.oas.models.parameters.QueryParameter;
73+
import io.swagger.v3.oas.models.security.Scopes;
74+
import io.swagger.v3.oas.models.servers.ServerVariables;
75+
import org.apache.commons.lang3.reflect.FieldUtils;
76+
import org.springdoc.core.configuration.SpringDocNativeConfiguration;
77+
import org.springdoc.core.properties.SpringDocConfigProperties.ModelConverters;
78+
79+
import org.springframework.aot.hint.MemberCategory;
80+
import org.springframework.aot.hint.RuntimeHints;
81+
import org.springframework.aot.hint.RuntimeHintsRegistrar;
82+
83+
/**
84+
* The type Spring doc hints.
85+
* @author bnasslahsen
86+
*/
87+
public class SpringDocHints implements RuntimeHintsRegistrar {
88+
89+
//swagger-models
90+
static Class[] swaggerModels = {
91+
io.swagger.v3.oas.models.security.SecurityScheme.Type.class,
92+
io.swagger.v3.oas.models.security.SecurityScheme.In.class,
93+
io.swagger.v3.oas.models.media.Encoding.class,
94+
io.swagger.v3.oas.models.info.Contact.class,
95+
io.swagger.v3.oas.models.info.License.class,
96+
io.swagger.v3.oas.models.security.OAuthFlow.class, io.swagger.v3.oas.models.security.OAuthFlows.class,
97+
io.swagger.v3.oas.models.security.SecurityScheme.class,
98+
io.swagger.v3.oas.models.tags.Tag.class,
99+
io.swagger.v3.oas.models.servers.ServerVariable.class,
100+
io.swagger.v3.oas.models.servers.Server.class,
101+
io.swagger.v3.oas.models.security.SecurityRequirement.class,
102+
io.swagger.v3.oas.models.info.Info.class,
103+
io.swagger.v3.oas.models.parameters.RequestBody.class,
104+
io.swagger.v3.oas.models.media.Schema.class,
105+
io.swagger.v3.oas.models.media.Content.class,
106+
io.swagger.v3.oas.models.media.ArraySchema.class,
107+
io.swagger.v3.oas.models.responses.ApiResponse.class,
108+
io.swagger.v3.oas.models.responses.ApiResponses.class,
109+
io.swagger.v3.oas.models.ExternalDocumentation.class,
110+
io.swagger.v3.oas.models.links.LinkParameter.class,
111+
io.swagger.v3.oas.models.links.Link.class,
112+
io.swagger.v3.oas.models.parameters.Parameter.class,
113+
io.swagger.v3.oas.models.Operation.class,
114+
io.swagger.v3.oas.models.headers.Header.class,
115+
ModelConverter.class,
116+
ModelConverters.class,
117+
SpecFilter.class,
118+
MediaType.class,
119+
ApiResponsesSerializer.class,
120+
PathsSerializer.class,
121+
ComponentsMixin.class,
122+
ExtensionsMixin.class,
123+
OpenAPIMixin.class,
124+
OperationMixin.class,
125+
SchemaMixin.class,
126+
Schema31Mixin.class,
127+
Components31Mixin.class,
128+
OpenAPI31Mixin.class,
129+
Discriminator31Mixin.class,
130+
Paths.class,
131+
XML.class,
132+
UUIDSchema.class,
133+
PathItem.class,
134+
ServerVariables.class,
135+
OpenAPI.class,
136+
Components.class,
137+
StringSchema.class,
138+
DateTimeSchema.class,
139+
Discriminator.class,
140+
BooleanSchema.class,
141+
FileSchema.class,
142+
IntegerSchema.class,
143+
MapSchema.class,
144+
ObjectSchema.class,
145+
Scopes.class,
146+
DateSchema.class,
147+
ComposedSchema.class,
148+
BinarySchema.class,
149+
ByteArraySchema.class,
150+
EmailSchema.class,
151+
Example.class,
152+
EncodingProperty.class,
153+
NumberSchema.class,
154+
PasswordSchema.class,
155+
CookieParameter.class,
156+
HeaderParameter.class,
157+
PathParameter.class,
158+
QueryParameter.class,
159+
DateSchemaMixin.class,
160+
ExampleMixin.class,
161+
MediaTypeMixin.class,
162+
};
163+
164+
@Override
165+
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
166+
hints.proxies()
167+
.registerJdkProxy(org.springframework.web.context.request.NativeWebRequest.class);
168+
//swagger-models
169+
Arrays.stream(swaggerModels).forEach(aClass ->
170+
hints.reflection().registerType(aClass,
171+
(hint) -> hint.withMembers(
172+
MemberCategory.DECLARED_FIELDS,
173+
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
174+
MemberCategory.INVOKE_DECLARED_METHODS
175+
)));
176+
177+
//springdoc
178+
hints.reflection().registerField(FieldUtils.getDeclaredField(io.swagger.v3.core.converter.ModelConverters.class, "converters", true));
179+
hints.reflection().registerType(org.springdoc.core.utils.Constants.class, (hint) -> hint.withMembers(MemberCategory.DECLARED_FIELDS));
180+
hints.resources().registerPattern(SpringDocNativeConfiguration.SPRINGDOC_CONFIG_PROPERTIES)
181+
.registerResourceBundle("sun.util.resources.LocaleNames");
182+
}
183+
184+
}
185+

0 commit comments

Comments
 (0)