@@ -3098,6 +3098,7 @@ public CodegenModel fromModel(String name, Schema schema) {
30983098 listOLists .add (m .requiredVars );
30993099 listOLists .add (m .vars );
31003100 listOLists .add (m .allVars );
3101+ listOLists .add (m .readWriteVars );
31013102 for (List <CodegenProperty > theseVars : listOLists ) {
31023103 for (CodegenProperty requiredVar : theseVars ) {
31033104 if (discPropName .equals (requiredVar .baseName )) {
@@ -3131,6 +3132,63 @@ public CodegenModel fromModel(String name, Schema schema) {
31313132 return m ;
31323133 }
31333134
3135+ /**
3136+ * Sets the default value for an enum discriminator property in the provided {@link CodegenModel}.
3137+ * <p>
3138+ * If the model's discriminator is defined, this method identifies the discriminator properties among the model's
3139+ * variables and assigns the default value to reflect the corresponding enum value for the model type.
3140+ * </p>
3141+ * <p>
3142+ * Example: If the discriminator is for type `Animal`, and the model is `Cat`, the default value
3143+ * will be set to `Animal.Cat` for the properties that have the same name as the discriminator.
3144+ * </p>
3145+ *
3146+ * @param model the {@link CodegenModel} whose discriminator property default value is to be set
3147+ */
3148+ protected static void setEnumDiscriminatorDefaultValue (CodegenModel model ) {
3149+ if (model .discriminator == null ) {
3150+ return ;
3151+ }
3152+ String discPropName = model .discriminator .getPropertyBaseName ();
3153+ Stream .of (model .requiredVars , model .vars , model .allVars , model .readWriteVars )
3154+ .flatMap (List ::stream )
3155+ .filter (v -> discPropName .equals (v .baseName ))
3156+ .forEach (v -> v .defaultValue = getEnumValueForProperty (model .schemaName , model .discriminator , v ));
3157+ }
3158+
3159+ /**
3160+ * Retrieves the appropriate default value for an enum discriminator property based on the model name.
3161+ * <p>
3162+ * If the discriminator has a mapping defined, it attempts to find a mapping for the model name.
3163+ * Otherwise, it defaults to one of the allowable enum value associated with the property.
3164+ * If no suitable value is found, the original default value of the property is returned.
3165+ * </p>
3166+ *
3167+ * @param modelName the name of the model to determine the default value for
3168+ * @param discriminator the {@link CodegenDiscriminator} containing the mapping and enum details
3169+ * @param var the {@link CodegenProperty} representing the discriminator property
3170+ * @return the default value for the enum discriminator property, or its original default value if none is found
3171+ */
3172+ protected static String getEnumValueForProperty (
3173+ String modelName , CodegenDiscriminator discriminator , CodegenProperty var ) {
3174+ if (!discriminator .getIsEnum () && !var .isEnum ) {
3175+ return var .defaultValue ;
3176+ }
3177+ Map <String , String > mapping = Optional .ofNullable (discriminator .getMapping ()).orElseGet (Collections ::emptyMap );
3178+ for (Map .Entry <String , String > e : mapping .entrySet ()) {
3179+ String schemaName = e .getValue ().indexOf ('/' ) < 0 ? e .getValue () : ModelUtils .getSimpleRef (e .getValue ());
3180+ if (modelName .equals (schemaName )) {
3181+ return e .getKey ();
3182+ }
3183+ }
3184+ Object values = var .allowableValues .get ("values" );
3185+ if (!(values instanceof List <?>)) {
3186+ return var .defaultValue ;
3187+ }
3188+ List <?> valueList = (List <?>) values ;
3189+ return valueList .stream ().filter (o -> o .equals (modelName )).map (o -> (String ) o ).findAny ().orElse (var .defaultValue );
3190+ }
3191+
31343192 protected void SortModelPropertiesByRequiredFlag (CodegenModel model ) {
31353193 Comparator <CodegenProperty > comparator = new Comparator <CodegenProperty >() {
31363194 @ Override
@@ -3201,15 +3259,19 @@ protected void setAddProps(Schema schema, IJsonSchemaValidationProperties proper
32013259 * @param visitedSchemas A set of visited schema names
32023260 */
32033261 private CodegenProperty discriminatorFound (String composedSchemaName , Schema sc , String discPropName , Set <String > visitedSchemas ) {
3204- if (visitedSchemas .contains (composedSchemaName )) { // recursive schema definition found
3262+ Schema refSchema = ModelUtils .getReferencedSchema (openAPI , sc );
3263+ String schemaName = Optional .ofNullable (composedSchemaName )
3264+ .or (() -> Optional .ofNullable (refSchema .getName ()))
3265+ .or (() -> Optional .ofNullable (sc .get$ref ()).map (ModelUtils ::getSimpleRef ))
3266+ .orElseGet (sc ::toString );
3267+ if (visitedSchemas .contains (schemaName )) { // recursive schema definition found
32053268 return null ;
32063269 } else {
3207- visitedSchemas .add (composedSchemaName );
3270+ visitedSchemas .add (schemaName );
32083271 }
32093272
3210- Schema refSchema = ModelUtils .getReferencedSchema (openAPI , sc );
32113273 if (refSchema .getProperties () != null && refSchema .getProperties ().get (discPropName ) != null ) {
3212- Schema discSchema = ( Schema ) refSchema .getProperties ().get (discPropName );
3274+ Schema discSchema = ModelUtils . getReferencedSchema ( openAPI , ( Schema )refSchema .getProperties ().get (discPropName ) );
32133275 CodegenProperty cp = new CodegenProperty ();
32143276 if (ModelUtils .isStringSchema (discSchema )) {
32153277 cp .isString = true ;
@@ -3218,14 +3280,16 @@ private CodegenProperty discriminatorFound(String composedSchemaName, Schema sc,
32183280 if (refSchema .getRequired () != null && refSchema .getRequired ().contains (discPropName )) {
32193281 cp .setRequired (true );
32203282 }
3283+ cp .setIsEnum (discSchema .getEnum () != null && !discSchema .getEnum ().isEmpty ());
32213284 return cp ;
32223285 }
32233286 if (ModelUtils .isComposedSchema (refSchema )) {
32243287 Schema composedSchema = refSchema ;
32253288 if (composedSchema .getAllOf () != null ) {
32263289 // If our discriminator is in one of the allOf schemas break when we find it
32273290 for (Object allOf : composedSchema .getAllOf ()) {
3228- CodegenProperty cp = discriminatorFound (composedSchemaName , (Schema ) allOf , discPropName , visitedSchemas );
3291+ Schema allOfSchema = (Schema ) allOf ;
3292+ CodegenProperty cp = discriminatorFound (allOfSchema .getName (), allOfSchema , discPropName , visitedSchemas );
32293293 if (cp != null ) {
32303294 return cp ;
32313295 }
@@ -3235,8 +3299,11 @@ private CodegenProperty discriminatorFound(String composedSchemaName, Schema sc,
32353299 // All oneOf definitions must contain the discriminator
32363300 CodegenProperty cp = new CodegenProperty ();
32373301 for (Object oneOf : composedSchema .getOneOf ()) {
3238- String modelName = ModelUtils .getSimpleRef (((Schema ) oneOf ).get$ref ());
3239- CodegenProperty thisCp = discriminatorFound (composedSchemaName , (Schema ) oneOf , discPropName , visitedSchemas );
3302+ Schema oneOfSchema = (Schema ) oneOf ;
3303+ String modelName = ModelUtils .getSimpleRef ((oneOfSchema ).get$ref ());
3304+ // Must use a copied set as the oneOf schemas can point to the same discriminator.
3305+ Set <String > visitedSchemasCopy = new TreeSet <>(visitedSchemas );
3306+ CodegenProperty thisCp = discriminatorFound (oneOfSchema .getName (), oneOfSchema , discPropName , visitedSchemasCopy );
32403307 if (thisCp == null ) {
32413308 once (LOGGER ).warn (
32423309 "'{}' defines discriminator '{}', but the referenced OneOf schema '{}' is missing {}" ,
@@ -3258,8 +3325,11 @@ private CodegenProperty discriminatorFound(String composedSchemaName, Schema sc,
32583325 // All anyOf definitions must contain the discriminator because a min of one must be selected
32593326 CodegenProperty cp = new CodegenProperty ();
32603327 for (Object anyOf : composedSchema .getAnyOf ()) {
3261- String modelName = ModelUtils .getSimpleRef (((Schema ) anyOf ).get$ref ());
3262- CodegenProperty thisCp = discriminatorFound (composedSchemaName , (Schema ) anyOf , discPropName , visitedSchemas );
3328+ Schema anyOfSchema = (Schema ) anyOf ;
3329+ String modelName = ModelUtils .getSimpleRef (anyOfSchema .get$ref ());
3330+ // Must use a copied set as the anyOf schemas can point to the same discriminator.
3331+ Set <String > visitedSchemasCopy = new TreeSet <>(visitedSchemas );
3332+ CodegenProperty thisCp = discriminatorFound (anyOfSchema .getName (), anyOfSchema , discPropName , visitedSchemasCopy );
32633333 if (thisCp == null ) {
32643334 once (LOGGER ).warn (
32653335 "'{}' defines discriminator '{}', but the referenced AnyOf schema '{}' is missing {}" ,
@@ -3542,13 +3612,11 @@ protected CodegenDiscriminator createDiscriminator(String schemaName, Schema sch
35423612 discriminator .setPropertyType (propertyType );
35433613
35443614 // check to see if the discriminator property is an enum string
3545- if (schema .getProperties () != null &&
3546- schema .getProperties ().get (discriminatorPropertyName ) instanceof StringSchema ) {
3547- StringSchema s = (StringSchema ) schema .getProperties ().get (discriminatorPropertyName );
3548- if (s .getEnum () != null && !s .getEnum ().isEmpty ()) { // it's an enum string
3549- discriminator .setIsEnum (true );
3550- }
3551- }
3615+ boolean isEnum = Optional
3616+ .ofNullable (discriminatorFound (schemaName , schema , discriminatorPropertyName , new TreeSet <>()))
3617+ .map (CodegenProperty ::getIsEnum )
3618+ .orElse (false );
3619+ discriminator .setIsEnum (isEnum );
35523620
35533621 discriminator .setMapping (sourceDiscriminator .getMapping ());
35543622 List <MappedModel > uniqueDescendants = new ArrayList <>();
0 commit comments