1616
1717package org .openapitools .codegen .languages ;
1818
19+ import com .google .common .collect .Sets ;
1920import io .swagger .v3 .core .util .Json ;
2021import io .swagger .v3 .oas .models .media .*;
2122import io .swagger .v3 .oas .models .media .ArraySchema ;
@@ -879,7 +880,7 @@ private String ensureQuotes(String in) {
879880
880881 public String toExampleValue (Schema schema , Object objExample ) {
881882 String modelName = getModelName (schema );
882- return toExampleValueRecursive (modelName , schema , objExample , 1 , "" , 0 );
883+ return toExampleValueRecursive (modelName , schema , objExample , 1 , "" , 0 , Sets . newHashSet () );
883884 }
884885
885886 private Boolean simpleStringSchema (Schema schema ) {
@@ -925,9 +926,12 @@ private MappedModel getDiscriminatorMappedModel(CodegenDiscriminator disc) {
925926 * ModelName( line 0
926927 * some_property='some_property_example' line 1
927928 * ) line 2
929+ * @param seenSchemas This set contains all the schemas passed into the recursive function. It is used to check
930+ * if a schema was already passed into the function and breaks the infinite recursive loop. The
931+ * only schemas that are not added are ones that contain $ref != null
928932 * @return the string example
929933 */
930- private String toExampleValueRecursive (String modelName , Schema schema , Object objExample , int indentationLevel , String prefix , Integer exampleLine ) {
934+ private String toExampleValueRecursive (String modelName , Schema schema , Object objExample , int indentationLevel , String prefix , Integer exampleLine , Set < Schema > seenSchemas ) {
931935 final String indentionConst = " " ;
932936 String currentIndentation = "" ;
933937 String closingIndentation = "" ;
@@ -951,6 +955,27 @@ private String toExampleValueRecursive(String modelName, Schema schema, Object o
951955 if (objExample != null ) {
952956 example = objExample .toString ();
953957 }
958+ // checks if the current schema has already been passed in. If so, breaks the current recursive pass
959+ if (seenSchemas .contains (schema )){
960+ if (modelName != null ) {
961+ return fullPrefix + modelName + closeChars ;
962+ } else {
963+ // this is a recursive schema
964+ // need to add a reasonable example to avoid
965+ // infinite recursion
966+ if (ModelUtils .isNullable (schema )) {
967+ // if the schema is nullable, then 'None' is a valid value
968+ return fullPrefix + "None" + closeChars ;
969+ } else if (ModelUtils .isArraySchema (schema )) {
970+ // the schema is an array, add an empty array
971+ return fullPrefix + "[]" + closeChars ;
972+ } else {
973+ // the schema is an object, make an empty object
974+ return fullPrefix + "{}" + closeChars ;
975+ }
976+ }
977+ }
978+
954979 if (null != schema .get$ref ()) {
955980 Map <String , Schema > allDefinitions = ModelUtils .getSchemas (this .openAPI );
956981 String ref = ModelUtils .getSimpleRef (schema .get$ref ());
@@ -960,7 +985,7 @@ private String toExampleValueRecursive(String modelName, Schema schema, Object o
960985 return fullPrefix + "None" + closeChars ;
961986 }
962987 String refModelName = getModelName (schema );
963- return toExampleValueRecursive (refModelName , refSchema , objExample , indentationLevel , prefix , exampleLine );
988+ return toExampleValueRecursive (refModelName , refSchema , objExample , indentationLevel , prefix , exampleLine , seenSchemas );
964989 } else if (ModelUtils .isNullType (schema ) || isAnyTypeSchema (schema )) {
965990 // The 'null' type is allowed in OAS 3.1 and above. It is not supported by OAS 3.0.x,
966991 // though this tooling supports it.
@@ -1058,7 +1083,8 @@ private String toExampleValueRecursive(String modelName, Schema schema, Object o
10581083 ArraySchema arrayschema = (ArraySchema ) schema ;
10591084 Schema itemSchema = arrayschema .getItems ();
10601085 String itemModelName = getModelName (itemSchema );
1061- example = fullPrefix + "[" + "\n " + toExampleValueRecursive (itemModelName , itemSchema , objExample , indentationLevel + 1 , "" , exampleLine + 1 ) + ",\n " + closingIndentation + "]" + closeChars ;
1086+ seenSchemas .add (schema );
1087+ example = fullPrefix + "[" + "\n " + toExampleValueRecursive (itemModelName , itemSchema , objExample , indentationLevel + 1 , "" , exampleLine + 1 , seenSchemas ) + ",\n " + closingIndentation + "]" + closeChars ;
10621088 return example ;
10631089 } else if (ModelUtils .isMapSchema (schema )) {
10641090 if (modelName == null ) {
@@ -1080,7 +1106,8 @@ private String toExampleValueRecursive(String modelName, Schema schema, Object o
10801106 addPropPrefix = ensureQuotes (key ) + ": " ;
10811107 }
10821108 String addPropsModelName = getModelName (addPropsSchema );
1083- example = fullPrefix + "\n " + toExampleValueRecursive (addPropsModelName , addPropsSchema , addPropsExample , indentationLevel + 1 , addPropPrefix , exampleLine + 1 ) + ",\n " + closingIndentation + closeChars ;
1109+ seenSchemas .add (schema );
1110+ example = fullPrefix + "\n " + toExampleValueRecursive (addPropsModelName , addPropsSchema , addPropsExample , indentationLevel + 1 , addPropPrefix , exampleLine + 1 , seenSchemas ) + ",\n " + closingIndentation + closeChars ;
10841111 } else {
10851112 example = fullPrefix + closeChars ;
10861113 }
@@ -1103,7 +1130,12 @@ private String toExampleValueRecursive(String modelName, Schema schema, Object o
11031130 return fullPrefix + closeChars ;
11041131 }
11051132 }
1106- return exampleForObjectModel (schema , fullPrefix , closeChars , null , indentationLevel , exampleLine , closingIndentation );
1133+ // Adds schema to seenSchemas before running example model function. romoves schema after running
1134+ // the function. It also doesnt keep track of any schemas within the ObjectModel.
1135+ seenSchemas .add (schema );
1136+ String exampleForObjectModel = exampleForObjectModel (schema , fullPrefix , closeChars , null , indentationLevel , exampleLine , closingIndentation , seenSchemas );
1137+ seenSchemas .remove (schema );
1138+ return exampleForObjectModel ;
11071139 } else if (ModelUtils .isComposedSchema (schema )) {
11081140 // TODO add examples for composed schema models without discriminators
11091141
@@ -1117,7 +1149,12 @@ private String toExampleValueRecursive(String modelName, Schema schema, Object o
11171149 CodegenProperty cp = new CodegenProperty ();
11181150 cp .setName (disc .getPropertyName ());
11191151 cp .setExample (discPropNameValue );
1120- return exampleForObjectModel (modelSchema , fullPrefix , closeChars , cp , indentationLevel , exampleLine , closingIndentation );
1152+ // Adds schema to seenSchemas before running example model function. romoves schema after running
1153+ // the function. It also doesnt keep track of any schemas within the ObjectModel.
1154+ seenSchemas .add (modelSchema );
1155+ String exampleForObjectModel = exampleForObjectModel (modelSchema , fullPrefix , closeChars , cp , indentationLevel , exampleLine , closingIndentation , seenSchemas );
1156+ seenSchemas .remove (modelSchema );
1157+ return exampleForObjectModel ;
11211158 } else {
11221159 return fullPrefix + closeChars ;
11231160 }
@@ -1130,7 +1167,7 @@ private String toExampleValueRecursive(String modelName, Schema schema, Object o
11301167 return example ;
11311168 }
11321169
1133- private String exampleForObjectModel (Schema schema , String fullPrefix , String closeChars , CodegenProperty discProp , int indentationLevel , int exampleLine , String closingIndentation ) {
1170+ private String exampleForObjectModel (Schema schema , String fullPrefix , String closeChars , CodegenProperty discProp , int indentationLevel , int exampleLine , String closingIndentation , Set < Schema > seenSchemas ) {
11341171 Map <String , Schema > requiredAndOptionalProps = schema .getProperties ();
11351172 if (requiredAndOptionalProps == null || requiredAndOptionalProps .isEmpty ()) {
11361173 return fullPrefix + closeChars ;
@@ -1150,7 +1187,7 @@ private String exampleForObjectModel(Schema schema, String fullPrefix, String cl
11501187 propModelName = getModelName (propSchema );
11511188 propExample = exampleFromStringOrArraySchema (propSchema , null , propName );
11521189 }
1153- example += toExampleValueRecursive (propModelName , propSchema , propExample , indentationLevel + 1 , propName + "=" , exampleLine + 1 ) + ",\n " ;
1190+ example += toExampleValueRecursive (propModelName , propSchema , propExample , indentationLevel + 1 , propName + "=" , exampleLine + 1 , seenSchemas ) + ",\n " ;
11541191 }
11551192 // TODO handle additionalProperties also
11561193 example += closingIndentation + closeChars ;
0 commit comments