Skip to content

Commit

Permalink
Merge pull request #571 from swagger-api/cc-19544
Browse files Browse the repository at this point in the history
fix html generator for composed schema properties
  • Loading branch information
frantuma authored Dec 27, 2019
2 parents d71093d + e3bbec4 commit d466104
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package io.swagger.codegen.v3.generators.html;

import io.swagger.codegen.v3.CodegenModel;
import io.swagger.codegen.v3.CodegenModelFactory;
import io.swagger.codegen.v3.CodegenModelType;
import io.swagger.codegen.v3.CodegenProperty;
import io.swagger.codegen.v3.generators.DefaultCodegenConfig;
import io.swagger.codegen.v3.generators.SchemaHandler;
import io.swagger.codegen.v3.generators.util.OpenAPIUtil;
import io.swagger.v3.oas.models.media.ComposedSchema;
import io.swagger.v3.oas.models.media.Schema;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;

public class HtmlSchemaHandler extends SchemaHandler {

public HtmlSchemaHandler(DefaultCodegenConfig codegenConfig) {
super(codegenConfig);
}


public void createCodegenModel(ComposedSchema composedProperty, CodegenProperty codegenProperty) {
final List<Schema> oneOf = composedProperty.getOneOf();
final List<Schema> anyOf = composedProperty.getAnyOf();

if (oneOf != null && !oneOf.isEmpty()) {
if (!hasNonObjectSchema(oneOf)) {
final CodegenModel oneOfModel = createFromOneOfSchemas(oneOf);
codegenProperty.vendorExtensions.put("oneOf-model", oneOfModel);
}
}
if (anyOf != null && !anyOf.isEmpty()) {
if (!hasNonObjectSchema(anyOf)) {
final CodegenModel anyOfModel = createFromOneOfSchemas(anyOf);
codegenProperty.vendorExtensions.put("anyOf-model", anyOfModel);
}
}

}

public void configureComposedModelFromSchemaItems(CodegenModel codegenModel, ComposedSchema items) {
List<Schema> oneOfList = items.getOneOf();
if (oneOfList != null && !oneOfList.isEmpty()){
String name = "OneOf" + codegenModel.name + "Items";
final CodegenModel oneOfModel = createComposedModel(name);
// setting name to be used as instance type on composed model.
items.addExtension("x-model-name", codegenConfig.toModelName(name));

final List<String> modelNames = new ArrayList<>();
for (Schema interfaceSchema : oneOfList) {
if (StringUtils.isNotBlank(interfaceSchema.get$ref())) {
String schemaName = OpenAPIUtil.getSimpleRef(interfaceSchema.get$ref());
modelNames.add(codegenConfig.toModelName(schemaName));
}
}
oneOfModel.vendorExtensions.put("x-model-names", modelNames);
if (!modelNames.isEmpty()) {
codegenModel.vendorExtensions.put("oneOf-model", oneOfModel);
}
}
List<Schema> anyOfList = items.getAnyOf();
if (anyOfList != null && !anyOfList.isEmpty()){
String name = "AnyOf" + codegenModel.name + "Items";
final CodegenModel anyOfModel = createComposedModel(name);
items.addExtension("x-model-name", codegenConfig.toModelName(name));

final List<String> modelNames = new ArrayList<>();
for (Schema interfaceSchema : anyOfList) {
if (StringUtils.isNotBlank(interfaceSchema.get$ref())) {
String schemaName = OpenAPIUtil.getSimpleRef(interfaceSchema.get$ref());
modelNames.add(codegenConfig.toModelName(schemaName));
}
}
anyOfModel.vendorExtensions.put("x-model-names", modelNames);
if (!modelNames.isEmpty()) {
codegenModel.vendorExtensions.put("anyOf-model", anyOfModel);
}
}
}

public void configureOneOfModel(CodegenModel codegenModel, List<Schema> oneOf) {
// no ops for html generator
}

public void configureAnyOfModel(CodegenModel codegenModel, List<Schema> anyOf) {
// no ops for html generator
}

public void configureOneOfModelFromProperty(CodegenProperty codegenProperty, CodegenModel codegenModel) {
// no ops for html generator
}

public void configureAnyOfModelFromProperty(CodegenProperty codegenProperty, CodegenModel codegenModel) {
// no ops for html generator
}

private CodegenModel createFromOneOfSchemas(List<Schema> schemas) {
final CodegenModel codegenModel = CodegenModelFactory.newInstance(CodegenModelType.MODEL);
final List<String> modelNames = new ArrayList<>();

for (Schema interfaceSchema : schemas) {
if (StringUtils.isNotBlank(interfaceSchema.get$ref())) {
String schemaName = OpenAPIUtil.getSimpleRef(interfaceSchema.get$ref());
modelNames.add(codegenConfig.toModelName(schemaName));
}
}
codegenModel.vendorExtensions.put("x-model-names", modelNames);
return codegenModel;
}

private CodegenModel createComposedModel(String name) {
final CodegenModel composedModel = CodegenModelFactory.newInstance(CodegenModelType.MODEL);
this.configureModel(composedModel, name);
return composedModel;
}

private void configureModel(CodegenModel codegenModel, String name) {
codegenModel.name = name;
codegenModel.classname = codegenConfig.toModelName(name);
codegenModel.classVarName = codegenConfig.toVarName(name);
codegenModel.classFilename = codegenConfig.toModelFilename(name);
codegenModel.vendorExtensions.put("x-is-composed-model", Boolean.TRUE);
}

private boolean hasNonObjectSchema(List<Schema> schemas) {
for (Schema schema : schemas) {
if (!codegenConfig.isObjectSchema(schema)) {
return true;
}
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public class StaticHtmlCodegen extends DefaultCodegenConfig {

public StaticHtmlCodegen() {
super();
schemaHandler = new HtmlSchemaHandler(this);
outputFolder = "docs";

defaultIncludes = new HashSet<String>();
Expand Down Expand Up @@ -155,7 +156,7 @@ public String escapeUnsafeCharacters(String input) {

/**
* Convert Markdown text to HTML
*
*
* @param input
* text in Markdown; may be null.
* @return the text, converted to Markdown. For null input, "" is returned.
Expand Down
30 changes: 30 additions & 0 deletions src/main/resources/handlebars/htmlDocs/index.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,36 @@
{{#example}}
<div class="param-desc"><span class="param-type">example: {{example}}</span></div>
{{/example}}
{{#vendorExtensions.oneOf-model}}
<div class="param-desc"><span class="param-type">oneOf:</span>
{{#vendorExtensions.x-model-names}}
<a href="#{{this}}"><code>{{this}}</code></a>&nbsp;&nbsp;&nbsp;
{{/vendorExtensions.x-model-names}}
</div>
{{/vendorExtensions.oneOf-model}}
{{#vendorExtensions.anyOf-model}}
<div class="param-desc"><span class="param-type">anyOf:</span>
{{#vendorExtensions.x-model-names}}
<a href="#{{this}}"><code>{{this}}</code></a>&nbsp;&nbsp;&nbsp;
{{/vendorExtensions.x-model-names}}
</div>
{{/vendorExtensions.anyOf-model}}
{{#items}}
{{#vendorExtensions.oneOf-model}}
<div class="param-desc"><span class="param-type">items oneOf:</span>
{{#vendorExtensions.x-model-names}}
<a href="#{{this}}"><code>{{this}}</code></a>&nbsp;&nbsp;&nbsp;
{{/vendorExtensions.x-model-names}}
</div>
{{/vendorExtensions.oneOf-model}}
{{#vendorExtensions.anyOf-model}}
<div class="param-desc"><span class="param-type">items anyOf:</span>
{{#vendorExtensions.x-model-names}}
<a href="#{{this}}"><code>{{this}}</code></a>&nbsp;&nbsp;&nbsp;
{{/vendorExtensions.x-model-names}}
</div>
{{/vendorExtensions.anyOf-model}}
{{/items}}
{{/vars}}
</div> <!-- field-items -->
</div>
Expand Down

0 comments on commit d466104

Please sign in to comment.