Skip to content

Commit e1c4fdb

Browse files
authored
fix discriminator model lookup when used with model name suffix (#23363)
1 parent 8a2f1bb commit e1c4fdb

3 files changed

Lines changed: 57 additions & 6 deletions

File tree

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,18 +76,27 @@ public static class MappedModel implements Comparable<MappedModel> {
7676
// is converted to a sanitized, internal representation within codegen.
7777
@Getter @Setter
7878
private String modelName;
79+
// The raw schema name as it appears in the OAS document, before any
80+
// modelNamePrefix/Suffix transformation.
81+
@Getter
82+
private String schemaName;
7983

8084
@Getter @Setter
8185
private CodegenModel model;
8286

8387
private final boolean explicitMapping;
8488

85-
public MappedModel(String mappingName, String modelName, boolean explicitMapping) {
89+
public MappedModel(String mappingName, String modelName, String schemaName, boolean explicitMapping) {
8690
this.mappingName = mappingName;
8791
this.modelName = modelName;
92+
this.schemaName = schemaName;
8893
this.explicitMapping = explicitMapping;
8994
}
9095

96+
public MappedModel(String mappingName, String modelName, boolean explicitMapping) {
97+
this(mappingName, modelName, null, explicitMapping);
98+
}
99+
91100
public boolean isExplicitMapping() {
92101
return explicitMapping;
93102
}

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,8 @@ public Map<String, ModelsMap> postProcessAllModels(Map<String, ModelsMap> objs)
507507
// add the model to the discriminator's mapping so templates have access to more than just the string to string mapping
508508
if (model.discriminator != null && model.discriminator.getMappedModels() != null) {
509509
for (CodegenDiscriminator.MappedModel mappedModel : model.discriminator.getMappedModels()) {
510-
CodegenModel mappedCodegenModel = ModelUtils.getModelByName(mappedModel.getModelName(), objs);
510+
String lookupName = mappedModel.getSchemaName() != null ? mappedModel.getSchemaName() : mappedModel.getModelName();
511+
CodegenModel mappedCodegenModel = ModelUtils.getModelByName(lookupName, objs);
511512
mappedModel.setModel(mappedCodegenModel);
512513
}
513514
}
@@ -3574,7 +3575,7 @@ protected List<MappedModel> getOneOfAnyOfDescendants(String composedSchemaName,
35743575
once(LOGGER).warn("'{}' defines discriminator '{}', but the referenced schema '{}' is incorrect. {}",
35753576
composedSchemaName, discPropName, modelName, msgSuffix);
35763577
}
3577-
MappedModel mm = new MappedModel(modelName, toModelName(modelName));
3578+
MappedModel mm = new MappedModel(modelName, toModelName(modelName), modelName, false);
35783579
descendentSchemas.add(mm);
35793580
Schema cs = ModelUtils.getSchema(openAPI, modelName);
35803581
if (cs == null) { // cannot lookup the model based on the name
@@ -3583,7 +3584,7 @@ protected List<MappedModel> getOneOfAnyOfDescendants(String composedSchemaName,
35833584
Map<String, Object> vendorExtensions = cs.getExtensions();
35843585
if (vendorExtensions != null && !vendorExtensions.isEmpty() && vendorExtensions.containsKey(X_DISCRIMINATOR_VALUE)) {
35853586
String xDiscriminatorValue = (String) vendorExtensions.get(X_DISCRIMINATOR_VALUE);
3586-
mm = new MappedModel(xDiscriminatorValue, toModelName(modelName), true);
3587+
mm = new MappedModel(xDiscriminatorValue, toModelName(modelName), modelName, true);
35873588
descendentSchemas.add(mm);
35883589
}
35893590
}
@@ -3641,7 +3642,7 @@ protected List<MappedModel> getAllOfDescendants(String thisSchemaName) {
36413642
.map(ve -> ve.get(X_DISCRIMINATOR_VALUE))
36423643
.map(discriminatorValue -> (String) discriminatorValue)
36433644
.orElse(currentSchemaName);
3644-
MappedModel mm = new MappedModel(mappingName, toModelName(currentSchemaName), !mappingName.equals(currentSchemaName));
3645+
MappedModel mm = new MappedModel(mappingName, toModelName(currentSchemaName), currentSchemaName, !mappingName.equals(currentSchemaName));
36453646
descendentSchemas.add(mm);
36463647
}
36473648
return descendentSchemas;
@@ -3687,7 +3688,7 @@ protected CodegenDiscriminator createDiscriminator(String schemaName, Schema sch
36873688
} else {
36883689
name = e.getValue();
36893690
}
3690-
uniqueDescendants.add(new MappedModel(e.getKey(), toModelName(name), true));
3691+
uniqueDescendants.add(new MappedModel(e.getKey(), toModelName(name), name, true));
36913692
}
36923693
}
36933694

modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1680,6 +1680,47 @@ public void testComposedSchemaOneOfDiscriminatorMapPreAndPostFix() {
16801680
assertThat(cm.discriminator.getPropertyType()).isEqualTo("TransferFruitTypeEnumDto");
16811681
}
16821682

1683+
@Test
1684+
public void testDiscriminatorMappedModelWithModelNameSuffix() {
1685+
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/oneOfDiscriminator.yaml");
1686+
DefaultCodegen codegen = new DefaultCodegen();
1687+
codegen.setLegacyDiscriminatorBehavior(false);
1688+
codegen.setOpenAPI(openAPI);
1689+
codegen.setModelNameSuffix("Dto");
1690+
1691+
// Build allProcessedModels map keyed by raw schema name (as DefaultGenerator does)
1692+
Map<String, ModelsMap> allProcessedModels = new TreeMap<>();
1693+
String[] schemaNames = {"FruitReqDisc", "AppleReqDisc", "BananaReqDisc"};
1694+
for (String name : schemaNames) {
1695+
Schema schema = openAPI.getComponents().getSchemas().get(name);
1696+
CodegenModel cm = codegen.fromModel(name, schema);
1697+
ModelMap mo = new ModelMap();
1698+
mo.setModel(cm);
1699+
ModelsMap models = new ModelsMap();
1700+
models.setModels(Collections.singletonList(mo));
1701+
allProcessedModels.put(name, models);
1702+
}
1703+
1704+
// Verify schemaName is stored and differs from modelName
1705+
CodegenModel fruitModel = ModelUtils.getModelByName("FruitReqDisc", allProcessedModels);
1706+
assertNotNull(fruitModel.discriminator);
1707+
for (CodegenDiscriminator.MappedModel mm : fruitModel.discriminator.getMappedModels()) {
1708+
assertNotNull(mm.getSchemaName(),
1709+
"MappedModel.getSchemaName() should not be null for " + mm.getModelName());
1710+
assertNotEquals(mm.getSchemaName(), mm.getModelName(),
1711+
"schemaName should differ from modelName when modelNameSuffix is set");
1712+
}
1713+
1714+
// Verify postProcessAllModels resolves MappedModel.model via schemaName
1715+
Map<String, ModelsMap> result = codegen.postProcessAllModels(allProcessedModels);
1716+
fruitModel = ModelUtils.getModelByName("FruitReqDisc", result);
1717+
for (CodegenDiscriminator.MappedModel mm : fruitModel.discriminator.getMappedModels()) {
1718+
assertNotNull(mm.getModel(),
1719+
"MappedModel.getModel() should not be null for " + mm.getModelName()
1720+
+ " (mappingName=" + mm.getMappingName() + ")");
1721+
}
1722+
}
1723+
16831724
@Test
16841725
public void testComposedSchemaMyPetsOneOfDiscriminatorMap() {
16851726
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/allOf_composition_discriminator.yaml");

0 commit comments

Comments
 (0)