forked from loafle/openapi-generator-original
[Kotlin] Fix Spring Kotlin generation of array/map models (#7829)
* Fix Spring Kotlin generation of array/map models * update doc Co-authored-by: William Cheng <wing328hk@gmail.com>
This commit is contained in:
parent
4f1934c3c7
commit
ca3fcd882e
@ -47,7 +47,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|
|||||||
|
|
||||||
| Type/Alias | Instantiated By |
|
| Type/Alias | Instantiated By |
|
||||||
| ---------- | --------------- |
|
| ---------- | --------------- |
|
||||||
|array|kotlin.Array|
|
|array|kotlin.collections.ArrayList|
|
||||||
|list|kotlin.collections.ArrayList|
|
|list|kotlin.collections.ArrayList|
|
||||||
|map|kotlin.collections.HashMap|
|
|map|kotlin.collections.HashMap|
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|
|||||||
|
|
||||||
| Type/Alias | Instantiated By |
|
| Type/Alias | Instantiated By |
|
||||||
| ---------- | --------------- |
|
| ---------- | --------------- |
|
||||||
|array|kotlin.Array|
|
|array|kotlin.collections.ArrayList|
|
||||||
|list|kotlin.collections.ArrayList|
|
|list|kotlin.collections.ArrayList|
|
||||||
|map|kotlin.collections.HashMap|
|
|map|kotlin.collections.HashMap|
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|
|||||||
|
|
||||||
| Type/Alias | Instantiated By |
|
| Type/Alias | Instantiated By |
|
||||||
| ---------- | --------------- |
|
| ---------- | --------------- |
|
||||||
|array|kotlin.Array|
|
|array|kotlin.collections.ArrayList|
|
||||||
|list|kotlin.collections.ArrayList|
|
|list|kotlin.collections.ArrayList|
|
||||||
|map|kotlin.collections.HashMap|
|
|map|kotlin.collections.HashMap|
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|
|||||||
|
|
||||||
| Type/Alias | Instantiated By |
|
| Type/Alias | Instantiated By |
|
||||||
| ---------- | --------------- |
|
| ---------- | --------------- |
|
||||||
|array|kotlin.Array|
|
|array|kotlin.collections.ArrayList|
|
||||||
|list|kotlin.collections.ArrayList|
|
|list|kotlin.collections.ArrayList|
|
||||||
|map|kotlin.collections.HashMap|
|
|map|kotlin.collections.HashMap|
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ package org.openapitools.codegen.languages;
|
|||||||
|
|
||||||
import io.swagger.v3.oas.models.media.ArraySchema;
|
import io.swagger.v3.oas.models.media.ArraySchema;
|
||||||
import io.swagger.v3.oas.models.media.Schema;
|
import io.swagger.v3.oas.models.media.Schema;
|
||||||
|
import io.swagger.v3.oas.models.media.StringSchema;
|
||||||
import org.apache.commons.io.FilenameUtils;
|
import org.apache.commons.io.FilenameUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.openapitools.codegen.CliOption;
|
import org.openapitools.codegen.CliOption;
|
||||||
@ -163,7 +164,7 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
|
|||||||
typeMapping.put("Date", "java.time.LocalDate");
|
typeMapping.put("Date", "java.time.LocalDate");
|
||||||
typeMapping.put("DateTime", "java.time.LocalDateTime");
|
typeMapping.put("DateTime", "java.time.LocalDateTime");
|
||||||
|
|
||||||
instantiationTypes.put("array", "kotlin.Array");
|
instantiationTypes.put("array", "kotlin.collections.ArrayList");
|
||||||
instantiationTypes.put("list", "kotlin.collections.ArrayList");
|
instantiationTypes.put("list", "kotlin.collections.ArrayList");
|
||||||
instantiationTypes.put("map", "kotlin.collections.HashMap");
|
instantiationTypes.put("map", "kotlin.collections.HashMap");
|
||||||
|
|
||||||
@ -308,15 +309,23 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getTypeDeclaration(Schema p) {
|
public String getTypeDeclaration(Schema p) {
|
||||||
if (ModelUtils.isArraySchema(p)) {
|
Schema<?> schema = ModelUtils.unaliasSchema(this.openAPI, p, importMapping);
|
||||||
return getArrayTypeDeclaration((ArraySchema) p);
|
Schema<?> target = ModelUtils.isGenerateAliasAsModel() ? p : schema;
|
||||||
} else if (ModelUtils.isMapSchema(p)) {
|
if (ModelUtils.isArraySchema(target)) {
|
||||||
Schema inner = getAdditionalProperties(p);
|
Schema<?> items = getSchemaItems((ArraySchema) schema);
|
||||||
|
return getSchemaType(target) + "<" + getTypeDeclaration(items) + ">";
|
||||||
// Maps will be keyed only by primitive Kotlin string
|
} else if (ModelUtils.isMapSchema(target)) {
|
||||||
return getSchemaType(p) + "<kotlin.String, " + getTypeDeclaration(inner) + ">";
|
// Note: ModelUtils.isMapSchema(p) returns true when p is a composed schema that also defines
|
||||||
|
// additionalproperties: true
|
||||||
|
Schema<?> inner = getAdditionalProperties(target);
|
||||||
|
if (inner == null) {
|
||||||
|
LOGGER.error("`{}` (map property) does not have a proper inner type defined. Default to type:string", p.getName());
|
||||||
|
inner = new StringSchema().description("TODO default missing map inner type to string");
|
||||||
|
p.setAdditionalProperties(inner);
|
||||||
|
}
|
||||||
|
return getSchemaType(target) + "<kotlin.String, " + getTypeDeclaration(inner) + ">";
|
||||||
}
|
}
|
||||||
return super.getTypeDeclaration(p);
|
return super.getTypeDeclaration(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -548,14 +557,6 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
|
|||||||
return sanitizeKotlinSpecificNames(modified);
|
return sanitizeKotlinSpecificNames(modified);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toInstantiationType(Schema p) {
|
|
||||||
if (ModelUtils.isArraySchema(p)) {
|
|
||||||
return getArrayTypeDeclaration((ArraySchema) p);
|
|
||||||
}
|
|
||||||
return super.toInstantiationType(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toApiName(String name) {
|
public String toApiName(String name) {
|
||||||
if (name.length() == 0) {
|
if (name.length() == 0) {
|
||||||
@ -671,30 +672,6 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
|
|||||||
return toModelName(name);
|
return toModelName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides a strongly typed declaration for simple arrays of some type and arrays of arrays of some type.
|
|
||||||
*
|
|
||||||
* @param arr Array schema
|
|
||||||
* @return type declaration of array
|
|
||||||
*/
|
|
||||||
private String getArrayTypeDeclaration(ArraySchema arr) {
|
|
||||||
// TODO: collection type here should be fully qualified namespace to avoid model conflicts
|
|
||||||
// This supports arrays of arrays.
|
|
||||||
String arrayType;
|
|
||||||
if (ModelUtils.isSet(arr)) {
|
|
||||||
arrayType = typeMapping.get("set");
|
|
||||||
} else {
|
|
||||||
arrayType = typeMapping.get("array");
|
|
||||||
}
|
|
||||||
StringBuilder instantiationType = new StringBuilder(arrayType);
|
|
||||||
Schema items = arr.getItems();
|
|
||||||
String nestedType = getTypeDeclaration(items);
|
|
||||||
additionalProperties.put("nestedType", nestedType);
|
|
||||||
// TODO: We may want to differentiate here between generics and primitive arrays.
|
|
||||||
instantiationType.append("<").append(nestedType).append(">");
|
|
||||||
return instantiationType.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sanitize against Kotlin specific naming conventions, which may differ from those required by {@link DefaultCodegen#sanitizeName}.
|
* Sanitize against Kotlin specific naming conventions, which may differ from those required by {@link DefaultCodegen#sanitizeName}.
|
||||||
*
|
*
|
||||||
|
@ -5,13 +5,13 @@
|
|||||||
{{/vars}}
|
{{/vars}}
|
||||||
*/{{#discriminator}}
|
*/{{#discriminator}}
|
||||||
{{>typeInfoAnnotation}}{{/discriminator}}
|
{{>typeInfoAnnotation}}{{/discriminator}}
|
||||||
{{#discriminator}}interface {{classname}}{{/discriminator}}{{^discriminator}}data class {{classname}}(
|
{{#discriminator}}interface {{classname}}{{/discriminator}}{{^discriminator}}{{#hasVars}}data {{/hasVars}}class {{classname}}(
|
||||||
{{#requiredVars}}
|
{{#requiredVars}}
|
||||||
{{>dataClassReqVar}}{{^-last}},
|
{{>dataClassReqVar}}{{^-last}},
|
||||||
{{/-last}}{{/requiredVars}}{{#hasRequired}}{{#hasOptional}},
|
{{/-last}}{{/requiredVars}}{{#hasRequired}}{{#hasOptional}},
|
||||||
{{/hasOptional}}{{/hasRequired}}{{#optionalVars}}{{>dataClassOptVar}}{{^-last}},
|
{{/hasOptional}}{{/hasRequired}}{{#optionalVars}}{{>dataClassOptVar}}{{^-last}},
|
||||||
{{/-last}}{{/optionalVars}}
|
{{/-last}}{{/optionalVars}}
|
||||||
) {{/discriminator}}{{#parent}}: {{{parent}}}{{/parent}}{
|
) {{/discriminator}}{{#parent}}: {{{parent}}}(){{/parent}}{
|
||||||
{{#discriminator}}
|
{{#discriminator}}
|
||||||
{{#requiredVars}}
|
{{#requiredVars}}
|
||||||
{{>interfaceReqVar}}
|
{{>interfaceReqVar}}
|
||||||
|
@ -1 +1 @@
|
|||||||
@javax.annotation.Generated(value = "{{generatorClass}}"{{^hideGenerationTimestamp}}, date = "{{generatedDate}}"{{/hideGenerationTimestamp}})
|
@javax.annotation.Generated(value = ["{{generatorClass}}"]{{^hideGenerationTimestamp}}, date = "{{generatedDate}}"{{/hideGenerationTimestamp}})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user