Skip to content

Commit 6f212b2

Browse files
committed
Example demonstrating loss of type information with generics
1 parent db60468 commit 6f212b2

File tree

4 files changed

+215
-0
lines changed

4 files changed

+215
-0
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package test.org.springdoc.api.app88;
2+
3+
import java.util.UUID;
4+
import io.swagger.v3.oas.annotations.Operation;
5+
import io.swagger.v3.oas.annotations.parameters.RequestBody;
6+
import org.springframework.http.ResponseEntity;
7+
import org.springframework.web.bind.annotation.PathVariable;
8+
import org.springframework.web.bind.annotation.PutMapping;
9+
import org.springframework.web.bind.annotation.RestController;
10+
11+
@RestController("pet")
12+
public class PetController {
13+
14+
@PutMapping("/{petRecordId}")
15+
@Operation
16+
public ResponseEntity<PetController.PetRecord<?>> putPetRecord(
17+
@PathVariable UUID petRecordId,
18+
@RequestBody PetController.PetRecord<?> petRecord
19+
) {
20+
return ResponseEntity.ok(petRecord);
21+
}
22+
23+
static class PetRecord<T extends Pet> {
24+
private final String owner;
25+
private final T pet;
26+
27+
public PetRecord(String owner, T pet) {
28+
this.owner = owner;
29+
this.pet = pet;
30+
}
31+
32+
public String getOwner() {
33+
return owner;
34+
}
35+
36+
public T getPet() {
37+
return pet;
38+
}
39+
}
40+
41+
interface Pet {
42+
String getName();
43+
}
44+
45+
static class Cat implements Pet {
46+
private final String name;
47+
48+
Cat(String name) {this.name = name;}
49+
50+
@Override public String getName() {
51+
return name;
52+
}
53+
}
54+
55+
static class Dog implements Pet {
56+
private final String name;
57+
58+
Dog(String name) {this.name = name;}
59+
60+
@Override public String getName() {
61+
return name;
62+
}
63+
}
64+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package test.org.springdoc.api.app88;
2+
3+
import java.util.Iterator;
4+
import com.fasterxml.jackson.databind.type.SimpleType;
5+
import io.swagger.v3.core.converter.AnnotatedType;
6+
import io.swagger.v3.core.converter.ModelConverter;
7+
import io.swagger.v3.core.converter.ModelConverterContext;
8+
import io.swagger.v3.oas.models.media.ComposedSchema;
9+
import io.swagger.v3.oas.models.media.Schema;
10+
import org.springframework.stereotype.Component;
11+
12+
@Component
13+
public class PetModelConverter implements ModelConverter {
14+
@Override
15+
public Schema<?> resolve(
16+
AnnotatedType annotatedType,
17+
ModelConverterContext modelConverterContext,
18+
Iterator<ModelConverter> iterator) {
19+
if (annotatedType.getType() instanceof SimpleType && ((SimpleType)annotatedType.getType()).getRawClass().equals(PetController.Pet.class)) {
20+
modelConverterContext.defineModel("Cat", modelConverterContext.resolve(new AnnotatedType(PetController.Cat.class)));
21+
modelConverterContext.defineModel("Dog", modelConverterContext.resolve(new AnnotatedType(PetController.Dog.class)));
22+
return new ComposedSchema()
23+
.addOneOfItem(new Schema<>().$ref("#/components/schemas/Cat"))
24+
.addOneOfItem(new Schema<>().$ref("#/components/schemas/Dog"));
25+
} else {
26+
return iterator.next().resolve(annotatedType, modelConverterContext, iterator);
27+
}
28+
}
29+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
*
3+
* * Copyright 2019-2020 the original author or authors.
4+
* *
5+
* * Licensed under the Apache License, Version 2.0 (the "License");
6+
* * you may not use this file except in compliance with the License.
7+
* * You may obtain a copy of the License at
8+
* *
9+
* * https://www.apache.org/licenses/LICENSE-2.0
10+
* *
11+
* * Unless required by applicable law or agreed to in writing, software
12+
* * distributed under the License is distributed on an "AS IS" BASIS,
13+
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* * See the License for the specific language governing permissions and
15+
* * limitations under the License.
16+
*
17+
*/
18+
19+
package test.org.springdoc.api.app88;
20+
21+
import org.springframework.boot.autoconfigure.SpringBootApplication;
22+
import test.org.springdoc.api.AbstractSpringDocTest;
23+
24+
public class SpringDocApp88Test extends AbstractSpringDocTest {
25+
26+
@SpringBootApplication
27+
static class SpringDocTestApp {}
28+
29+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
{
2+
"openapi": "3.0.1",
3+
"info": {
4+
"title": "OpenAPI definition",
5+
"version": "v0"
6+
},
7+
"servers": [
8+
{
9+
"url": "http://localhost",
10+
"description": "Generated server url"
11+
}
12+
],
13+
"paths": {
14+
"/{petRecordId}": {
15+
"put": {
16+
"tags": [
17+
"pet-controller"
18+
],
19+
"operationId": "putPetRecord",
20+
"parameters": [
21+
{
22+
"name": "petRecordId",
23+
"in": "path",
24+
"required": true,
25+
"schema": {
26+
"type": "string",
27+
"format": "uuid"
28+
}
29+
}
30+
],
31+
"requestBody": {
32+
"content": {
33+
"application/json": {
34+
"schema": {
35+
"$ref": "#/components/schemas/PetRecord"
36+
}
37+
}
38+
}
39+
},
40+
"responses": {
41+
"200": {
42+
"description": "default response",
43+
"content": {
44+
"*/*": {
45+
"schema": {
46+
"$ref": "#/components/schemas/PetRecord"
47+
}
48+
}
49+
}
50+
}
51+
}
52+
}
53+
}
54+
},
55+
"components": {
56+
"schemas": {
57+
"Cat": {
58+
"type": "object",
59+
"properties": {
60+
"name": {
61+
"type": "string"
62+
}
63+
}
64+
},
65+
"Dog": {
66+
"type": "object",
67+
"properties": {
68+
"name": {
69+
"type": "string"
70+
}
71+
}
72+
},
73+
"PetRecord": {
74+
"type": "object",
75+
"properties": {
76+
"owner": {
77+
"type": "string"
78+
},
79+
"pet": {
80+
"oneOf": [
81+
{
82+
"$ref": "#/components/schemas/Cat"
83+
},
84+
{
85+
"$ref": "#/components/schemas/Dog"
86+
}
87+
]
88+
}
89+
}
90+
}
91+
}
92+
}
93+
}

0 commit comments

Comments
 (0)