Skip to content
Prev Previous commit
Next Next commit
Support for multiple levels of hierarchy in model objects
  • Loading branch information
roxspring committed Nov 15, 2019
commit dafa444c8013ed02cdbf864c4b9777b19df47307
Original file line number Diff line number Diff line change
Expand Up @@ -1789,7 +1789,7 @@ public CodegenModel fromModel(String name, Schema schema) {

// parent model
final String parentName = ModelUtils.getParentName(composed, allDefinitions);
final List<String> allParents = ModelUtils.getAllParentsName(composed, allDefinitions);
final List<String> allParents = ModelUtils.getAllParentsName(composed, allDefinitions, false);
final Schema parent = StringUtils.isBlank(parentName) || allDefinitions == null ? null : allDefinitions.get(parentName);
final boolean hasParent = StringUtils.isNotBlank(parentName);

Expand Down Expand Up @@ -1970,10 +1970,8 @@ private CodegenDiscriminator createDiscriminator(String schemaName, Schema schem
Map<String, Schema> allDefinitions = ModelUtils.getSchemas(this.openAPI);
allDefinitions.forEach((childName, child) -> {
if (child instanceof ComposedSchema && ((ComposedSchema) child).getAllOf() != null) {
Set<String> parentSchemas = ((ComposedSchema) child).getAllOf().stream()
.filter(s -> s.get$ref() != null)
.map(s -> ModelUtils.getSimpleRef(s.get$ref()))
.collect(Collectors.toSet());

final List<String> parentSchemas = ModelUtils.getAllParentsName((ComposedSchema) child, allDefinitions, true);
if (parentSchemas.contains(schemaName)) {
discriminator.getMappedModels().add(new MappedModel(childName, toModelName(childName)));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -923,7 +923,7 @@ public static String getParentName(ComposedSchema composedSchema, Map<String, Sc
if (s == null) {
LOGGER.error("Failed to obtain schema from {}", parentName);
return "UNKNOWN_PARENT_NAME";
} else if (s.getDiscriminator() != null && StringUtils.isNotEmpty(s.getDiscriminator().getPropertyName())) {
} else if (hasOrInheritsDiscriminator(s, allSchemas)) {
// discriminator.propertyName is used
return parentName;
} else {
Expand All @@ -947,7 +947,7 @@ public static String getParentName(ComposedSchema composedSchema, Map<String, Sc
return null;
}

public static List<String> getAllParentsName(ComposedSchema composedSchema, Map<String, Schema> allSchemas) {
public static List<String> getAllParentsName(ComposedSchema composedSchema, Map<String, Schema> allSchemas, boolean includeAncestors) {
List<Schema> interfaces = getInterfaces(composedSchema);
List<String> names = new ArrayList<String>();

Expand All @@ -960,9 +960,12 @@ public static List<String> getAllParentsName(ComposedSchema composedSchema, Map<
if (s == null) {
LOGGER.error("Failed to obtain schema from {}", parentName);
names.add("UNKNOWN_PARENT_NAME");
} else if (s.getDiscriminator() != null && StringUtils.isNotEmpty(s.getDiscriminator().getPropertyName())) {
} else if (hasOrInheritsDiscriminator(s, allSchemas)) {
// discriminator.propertyName is used
names.add(parentName);
if (includeAncestors && s instanceof ComposedSchema) {
names.addAll(getAllParentsName((ComposedSchema) s, allSchemas, true));
}
} else {
LOGGER.debug("Not a parent since discriminator.propertyName is not set {}", s.get$ref());
// not a parent since discriminator.propertyName is not set
Expand All @@ -976,6 +979,32 @@ public static List<String> getAllParentsName(ComposedSchema composedSchema, Map<
return names;
}

private static boolean hasOrInheritsDiscriminator(Schema schema, Map<String, Schema> allSchemas) {
if (schema.getDiscriminator() != null && StringUtils.isNotEmpty(schema.getDiscriminator().getPropertyName())) {
return true;
}
else if (StringUtils.isNotEmpty(schema.get$ref())) {
String parentName = getSimpleRef(schema.get$ref());
Schema s = allSchemas.get(parentName);
if (s != null) {
return hasOrInheritsDiscriminator(s, allSchemas);
}
else {
LOGGER.error("Failed to obtain schema from {}", parentName);
}
}
else if (schema instanceof ComposedSchema) {
final ComposedSchema composed = (ComposedSchema) schema;
final List<Schema> interfaces = getInterfaces(composed);
for (Schema i : interfaces) {
if (hasOrInheritsDiscriminator(i, allSchemas)) {
return true;
}
}
}
return false;
}

public static boolean isNullable(Schema schema) {
if (schema == null) {
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,7 @@ public void testDiscriminator() {
test.setPropertyName("className");
test.getMappedModels().add(new CodegenDiscriminator.MappedModel("Dog", "Dog"));
test.getMappedModels().add(new CodegenDiscriminator.MappedModel("Cat", "Cat"));
test.getMappedModels().add(new CodegenDiscriminator.MappedModel("BigCat", "BigCat"));
Assert.assertEquals(discriminator, test);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public void generateJsonAnnotationForPolymorphism() throws IOException {
String jsonSubType = "@JsonSubTypes({\n" +
" @JsonSubTypes.Type(value = Dog.class, name = \"Dog\"),\n" +
" @JsonSubTypes.Type(value = Cat.class, name = \"Cat\"),\n" +
" @JsonSubTypes.Type(value = BigDog.class, name = \"BigDog\"),\n" +
"})";
checkFileContains(generator, outputPath + "/src/gen/java/org/openapitools/model/Animal.java", jsonTypeInfo, jsonSubType);
}
Expand Down