|
18 | 18 |
|
19 | 19 | package org.springdoc.core; |
20 | 20 |
|
| 21 | +import com.fasterxml.jackson.core.JsonGenerator; |
| 22 | +import com.fasterxml.jackson.databind.SerializerProvider; |
| 23 | +import io.swagger.v3.core.converter.AnnotatedType; |
| 24 | +import io.swagger.v3.core.converter.ModelConverters; |
| 25 | +import io.swagger.v3.core.converter.ResolvedSchema; |
| 26 | +import io.swagger.v3.core.util.Json; |
| 27 | +import io.swagger.v3.oas.annotations.media.Schema; |
| 28 | +import io.swagger.v3.oas.models.media.MapSchema; |
| 29 | +import io.swagger.v3.oas.models.media.ObjectSchema; |
| 30 | +import io.swagger.v3.oas.models.media.StringSchema; |
21 | 31 | import org.springdoc.core.converters.PageableSupportConverter; |
22 | | - |
| 32 | +import org.springdoc.core.customizers.OpenApiCustomiser; |
23 | 33 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
24 | 34 | import org.springframework.context.annotation.Bean; |
25 | 35 | import org.springframework.context.annotation.Configuration; |
26 | 36 | import org.springframework.data.rest.core.config.RepositoryRestConfiguration; |
| 37 | +import org.springframework.hateoas.Link; |
| 38 | +import org.springframework.hateoas.Links; |
| 39 | +import org.springframework.hateoas.RepresentationModel; |
| 40 | +import org.springframework.hateoas.mediatype.hal.RepresentationModelMixin; |
27 | 41 |
|
28 | 42 | import static org.springdoc.core.Constants.SPRINGDOC_ENABLED; |
29 | 43 |
|
30 | 44 | @Configuration |
31 | 45 | @ConditionalOnProperty(name = SPRINGDOC_ENABLED, matchIfMissing = true) |
32 | 46 | public class SpringDocDataRestConfiguration { |
33 | 47 |
|
34 | | - @Bean |
35 | | - PageableSupportConverter pageableSupportConverter() { |
36 | | - return new PageableSupportConverter(); |
37 | | - } |
| 48 | + @Bean |
| 49 | + PageableSupportConverter pageableSupportConverter() { |
| 50 | + return new PageableSupportConverter(); |
| 51 | + } |
| 52 | + |
| 53 | + @Bean |
| 54 | + public HalProvider halProvider(RepositoryRestConfiguration repositoryRestConfiguration) { |
| 55 | + return new HalProvider(repositoryRestConfiguration); |
| 56 | + } |
| 57 | + |
| 58 | + /** |
| 59 | + * Registers an OpenApiCustomiser and a jackson mixin to ensure the definition of `Links` matches the serialized |
| 60 | + * output. This is done because the customer serializer converts the data to a map before serializing it. |
| 61 | + * |
| 62 | + * @see org.springframework.hateoas.mediatype.hal.Jackson2HalModule.HalLinkListSerializer#serialize(Links, JsonGenerator, SerializerProvider) |
| 63 | + */ |
| 64 | + @Bean |
| 65 | + public OpenApiCustomiser linksSchemaCustomiser(RepositoryRestConfiguration repositoryRestConfiguration) { |
| 66 | + if (!repositoryRestConfiguration.useHalAsDefaultJsonMediaType()) { |
| 67 | + return openApi -> {}; |
| 68 | + } |
| 69 | + Json.mapper().addMixIn(RepresentationModel.class, RepresentationModelLinksOASMixin.class); |
| 70 | + ResolvedSchema resolvedLinkSchema = ModelConverters.getInstance() |
| 71 | + .resolveAsResolvedSchema(new AnnotatedType(Link.class)); |
| 72 | + return openApi -> openApi |
| 73 | + .schema("Link", resolvedLinkSchema.schema) |
| 74 | + .schema("Links", new MapSchema() |
| 75 | + .additionalProperties(new StringSchema()) |
| 76 | + .additionalProperties(new ObjectSchema().$ref("#/components/schemas/Link"))); |
| 77 | + } |
38 | 78 |
|
39 | | - @Bean |
40 | | - public HalProvider halProvider(RepositoryRestConfiguration repositoryRestConfiguration) { |
41 | | - return new HalProvider(repositoryRestConfiguration); |
42 | | - } |
| 79 | + static abstract class RepresentationModelLinksOASMixin extends RepresentationModelMixin { |
| 80 | + @Override |
| 81 | + @Schema(ref = "#/components/schemas/Links") |
| 82 | + public abstract Links getLinks(); |
| 83 | + } |
43 | 84 | } |
0 commit comments