Skip to content

Commit d1ca82c

Browse files
committed
auto fix self-reference schemas
1 parent 462f450 commit d1ca82c

File tree

7 files changed

+103
-2
lines changed

7 files changed

+103
-2
lines changed

modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,12 +493,64 @@ private void normalizeComponentsSchemas() {
493493
}
494494
}
495495

496+
// auto fix self reference schema to avoid stack overflow
497+
fixSelfReferenceSchema(schemaName, schema);
498+
496499
// normalize the schemas
497500
schemas.put(schemaName, normalizeSchema(schema, new HashSet<>()));
498501
}
499502
}
500503
}
501504

505+
/**
506+
* Auto fix a self referencing schema using any type to replace the self-referencing sub-item.
507+
*
508+
* @param name Schema name
509+
* @param schema Schema
510+
*/
511+
public void fixSelfReferenceSchema(String name, Schema schema) {
512+
if (ModelUtils.isArraySchema(schema)) {
513+
if (isSelfReference(name, schema.getItems())) {
514+
LOGGER.error("Array schema {} has a sub-item referencing itself. Worked around the self-reference schema using any type instead.", name);
515+
schema.setItems(new Schema<>());
516+
}
517+
}
518+
519+
if (ModelUtils.isOneOf(schema)) {
520+
for (int i = 0; i < schema.getOneOf().size(); i++) {
521+
if (isSelfReference(name, (Schema) schema.getOneOf().get(i))) {
522+
LOGGER.error("oneOf schema {} has a sub-item referencing itself. Worked around the self-reference schema by removing it.", name);
523+
schema.getOneOf().remove(i);
524+
}
525+
}
526+
}
527+
528+
if (ModelUtils.isAnyOf(schema)) {
529+
for (int i = 0; i < schema.getAnyOf().size(); i++) {
530+
if (isSelfReference(name, (Schema) schema.getAnyOf().get(i))) {
531+
LOGGER.error("anyOf schema {} has a sub-item referencing itself. Worked around the self-reference schema by removing it.", name);
532+
schema.getAnyOf().remove(i);
533+
}
534+
}
535+
}
536+
537+
if (schema.getAdditionalProperties() != null && schema.getAdditionalProperties() instanceof Schema) {
538+
if (isSelfReference(name, (Schema) schema.getAdditionalProperties())) {
539+
LOGGER.error("Schema {} (with additional properties) has a sub-item referencing itself. Worked around the self-reference schema using any type instead.", name);
540+
schema.setAdditionalProperties(new Schema<>());
541+
}
542+
}
543+
544+
}
545+
546+
private boolean isSelfReference(String name, Schema subSchema) {
547+
if (subSchema != null && name.equals(ModelUtils.getSimpleRef(subSchema.get$ref()))) {
548+
return true;
549+
} else {
550+
return false;
551+
}
552+
}
553+
502554
/**
503555
* Normalizes a schema
504556
*

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1493,7 +1493,7 @@ public void setParameterExampleValue(CodegenParameter codegenParameter, RequestB
14931493
MediaType mediaType = content.values().iterator().next();
14941494
if (mediaType.getExample() != null) {
14951495
if (isModel) {
1496-
LOGGER.warn("Ignoring complex example on request body");
1496+
once(LOGGER).warn("Ignoring complex example on request body");
14971497
} else {
14981498
codegenParameter.example = mediaType.getExample().toString();
14991499
return;
@@ -1504,7 +1504,7 @@ public void setParameterExampleValue(CodegenParameter codegenParameter, RequestB
15041504
Example example = mediaType.getExamples().values().iterator().next();
15051505
if (example.getValue() != null) {
15061506
if (isModel) {
1507-
LOGGER.warn("Ignoring complex example on request body");
1507+
once(LOGGER).warn("Ignoring complex example on request body");
15081508
} else {
15091509
codegenParameter.example = example.getValue().toString();
15101510
return;

modules/openapi-generator/src/test/resources/3_1/java/petstore.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,3 +1066,24 @@ components:
10661066
- $ref: '#/components/schemas/SimpleModelWithArrayProperty'
10671067
myObject:
10681068
type: object
1069+
SelfReference:
1070+
type: array
1071+
items:
1072+
$ref: "#/components/schemas/SelfReference"
1073+
SelfReferenceOneOf:
1074+
oneOf:
1075+
- type: string
1076+
- type: boolean
1077+
- $ref: "#/components/schemas/SelfReferenceOneOf"
1078+
SelfReferenceAnyOf:
1079+
anyOf:
1080+
- type: string
1081+
- type: boolean
1082+
- $ref: "#/components/schemas/SelfReferenceAnyOf"
1083+
SelfReferenceAdditionalProperties:
1084+
type: object
1085+
additionalProperties:
1086+
$ref: "#/components/schemas/SelfReferenceAdditionalProperties"
1087+
properties:
1088+
dummy:
1089+
type: string

samples/client/petstore/java/okhttp-gson-3.1/.openapi-generator/FILES

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ docs/Pet.md
2424
docs/PetApi.md
2525
docs/RefRefToPathLevelParameterOneofRefToOneofParameter.md
2626
docs/RefToRefParameterAnyofRefToAnyofParameter.md
27+
docs/SelfReferenceAdditionalProperties.md
28+
docs/SelfReferenceAnyOf.md
29+
docs/SelfReferenceOneOf.md
2730
docs/SimpleModelWithArrayProperty.md
2831
docs/StoreApi.md
2932
docs/StringOrInt.md
@@ -82,6 +85,9 @@ src/main/java/org/openapitools/client/model/Order.java
8285
src/main/java/org/openapitools/client/model/Pet.java
8386
src/main/java/org/openapitools/client/model/RefRefToPathLevelParameterOneofRefToOneofParameter.java
8487
src/main/java/org/openapitools/client/model/RefToRefParameterAnyofRefToAnyofParameter.java
88+
src/main/java/org/openapitools/client/model/SelfReferenceAdditionalProperties.java
89+
src/main/java/org/openapitools/client/model/SelfReferenceAnyOf.java
90+
src/main/java/org/openapitools/client/model/SelfReferenceOneOf.java
8591
src/main/java/org/openapitools/client/model/SimpleModelWithArrayProperty.java
8692
src/main/java/org/openapitools/client/model/StringOrInt.java
8793
src/main/java/org/openapitools/client/model/Tag.java

samples/client/petstore/java/okhttp-gson-3.1/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,9 @@ Class | Method | HTTP request | Description
166166
- [Pet](docs/Pet.md)
167167
- [RefRefToPathLevelParameterOneofRefToOneofParameter](docs/RefRefToPathLevelParameterOneofRefToOneofParameter.md)
168168
- [RefToRefParameterAnyofRefToAnyofParameter](docs/RefToRefParameterAnyofRefToAnyofParameter.md)
169+
- [SelfReferenceAdditionalProperties](docs/SelfReferenceAdditionalProperties.md)
170+
- [SelfReferenceAnyOf](docs/SelfReferenceAnyOf.md)
171+
- [SelfReferenceOneOf](docs/SelfReferenceOneOf.md)
169172
- [SimpleModelWithArrayProperty](docs/SimpleModelWithArrayProperty.md)
170173
- [StringOrInt](docs/StringOrInt.md)
171174
- [Tag](docs/Tag.md)

samples/client/petstore/java/okhttp-gson-3.1/api/openapi.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,6 +1160,22 @@ components:
11601160
- $ref: '#/components/schemas/SimpleModelWithArrayProperty'
11611161
myObject:
11621162
type: object
1163+
SelfReference:
1164+
items: {}
1165+
type: array
1166+
SelfReferenceOneOf:
1167+
oneOf:
1168+
- type: string
1169+
- type: boolean
1170+
SelfReferenceAnyOf:
1171+
anyOf:
1172+
- type: string
1173+
- type: boolean
1174+
SelfReferenceAdditionalProperties:
1175+
additionalProperties: {}
1176+
properties:
1177+
dummy:
1178+
type: string
11631179
updatePetWithForm_request:
11641180
properties:
11651181
name:

samples/client/petstore/java/okhttp-gson-3.1/src/main/java/org/openapitools/client/JSON.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ private static Class getClassByDiscriminator(Map classByDiscriminatorValue, Stri
137137
gsonBuilder.registerTypeAdapterFactory(new org.openapitools.client.model.Pet.CustomTypeAdapterFactory());
138138
gsonBuilder.registerTypeAdapterFactory(new org.openapitools.client.model.RefRefToPathLevelParameterOneofRefToOneofParameter.CustomTypeAdapterFactory());
139139
gsonBuilder.registerTypeAdapterFactory(new org.openapitools.client.model.RefToRefParameterAnyofRefToAnyofParameter.CustomTypeAdapterFactory());
140+
gsonBuilder.registerTypeAdapterFactory(new org.openapitools.client.model.SelfReferenceAdditionalProperties.CustomTypeAdapterFactory());
141+
gsonBuilder.registerTypeAdapterFactory(new org.openapitools.client.model.SelfReferenceAnyOf.CustomTypeAdapterFactory());
142+
gsonBuilder.registerTypeAdapterFactory(new org.openapitools.client.model.SelfReferenceOneOf.CustomTypeAdapterFactory());
140143
gsonBuilder.registerTypeAdapterFactory(new org.openapitools.client.model.SimpleModelWithArrayProperty.CustomTypeAdapterFactory());
141144
gsonBuilder.registerTypeAdapterFactory(new org.openapitools.client.model.StringOrInt.CustomTypeAdapterFactory());
142145
gsonBuilder.registerTypeAdapterFactory(new org.openapitools.client.model.Tag.CustomTypeAdapterFactory());

0 commit comments

Comments
 (0)