[core] [regression] set parentName when a single possible parent exists (#3771)

Whilst the spec states that the 'allOf' relationship does not imply a hierarchy:

> While composition offers model extensibility, it does not imply a hierarchy between the models.
> To support polymorphism, the OpenAPI Specification adds the discriminator field.

Unfortunately this does not make sense for many existing use cases, that were supported by older
versions of the generator. Therefore, I've restored the older behavior, specifically
in the case that only a single possible parent schema is present.

I think a more complete solution would generate interfaces for the composed schemas,
and mark the generated class as implementing these.

fixes issue 2845, and fixes issue #3523
This commit is contained in:
Michael Nahkies 2019-08-28 13:31:38 +01:00 committed by William Cheng
parent 2016bc086f
commit 34ec98d17b
2 changed files with 15 additions and 4 deletions

View File

@ -896,6 +896,8 @@ public class ModelUtils {
public static String getParentName(ComposedSchema composedSchema, Map<String, Schema> allSchemas) { public static String getParentName(ComposedSchema composedSchema, Map<String, Schema> allSchemas) {
List<Schema> interfaces = getInterfaces(composedSchema); List<Schema> interfaces = getInterfaces(composedSchema);
List<String> refedParentNames = new ArrayList<>();
if (interfaces != null && !interfaces.isEmpty()) { if (interfaces != null && !interfaces.isEmpty()) {
for (Schema schema : interfaces) { for (Schema schema : interfaces) {
// get the actual schema // get the actual schema
@ -911,6 +913,7 @@ public class ModelUtils {
} else { } else {
LOGGER.debug("Not a parent since discriminator.propertyName is not set {}", s.get$ref()); LOGGER.debug("Not a parent since discriminator.propertyName is not set {}", s.get$ref());
// not a parent since discriminator.propertyName is not set // not a parent since discriminator.propertyName is not set
refedParentNames.add(parentName);
} }
} else { } else {
// not a ref, doing nothing // not a ref, doing nothing
@ -918,6 +921,13 @@ public class ModelUtils {
} }
} }
// parent name only makes sense when there is a single obvious parent
if (refedParentNames.size() == 1) {
LOGGER.warn("[deprecated] inheritance without use of 'discriminator.propertyName' is deprecated " +
"and will be removed in a future release. Generating model for {}", composedSchema.getName());
return refedParentNames.get(0);
}
return null; return null;
} }

View File

@ -32,9 +32,10 @@ import org.testng.annotations.Test;
public class JavaInheritanceTest { public class JavaInheritanceTest {
@Test(description = "convert a composed model without discriminator")
@Test(description = "convert a composed model with parent")
public void javaInheritanceTest() { public void javaInheritanceTest() {
final Schema allOfModel = new Schema().name("Base"); final Schema parentModel = new Schema().name("Base");
final Schema schema = new ComposedSchema() final Schema schema = new ComposedSchema()
.addAllOfItem(new Schema().$ref("Base")) .addAllOfItem(new Schema().$ref("Base"))
@ -42,7 +43,7 @@ public class JavaInheritanceTest {
OpenAPI openAPI = TestUtils.createOpenAPI(); OpenAPI openAPI = TestUtils.createOpenAPI();
openAPI.setComponents(new Components() openAPI.setComponents(new Components()
.addSchemas(allOfModel.getName(), allOfModel) .addSchemas(parentModel.getName(),parentModel)
.addSchemas(schema.getName(), schema) .addSchemas(schema.getName(), schema)
); );
@ -52,7 +53,7 @@ public class JavaInheritanceTest {
Assert.assertEquals(cm.name, "sample"); Assert.assertEquals(cm.name, "sample");
Assert.assertEquals(cm.classname, "Sample"); Assert.assertEquals(cm.classname, "Sample");
Assert.assertEquals(cm.parent, null); Assert.assertEquals(cm.parent, "Base");
Assert.assertEquals(cm.imports, Sets.newHashSet("Base")); Assert.assertEquals(cm.imports, Sets.newHashSet("Base"));
} }