diff --git a/.github/workflows/samples-kotlin-server-jdk17.yaml b/.github/workflows/samples-kotlin-server-jdk17.yaml
index 2669108f94c4..eab06c1a8f62 100644
--- a/.github/workflows/samples-kotlin-server-jdk17.yaml
+++ b/.github/workflows/samples-kotlin-server-jdk17.yaml
@@ -3,6 +3,7 @@ name: Samples Kotlin server (jdk17)
on:
push:
paths:
+ - 'samples/server/others/kotlin-server/**'
- 'samples/server/petstore/kotlin-springboot-3*/**'
- 'samples/server/petstore/kotlin-server/**'
- 'samples/server/petstore/kotlin-server-modelMutable/**'
@@ -13,6 +14,7 @@ on:
# - samples/server/petstore/kotlin-spring-default/**
pull_request:
paths:
+ - 'samples/server/others/kotlin-server/**'
- 'samples/server/petstore/kotlin-springboot-3*/**'
- 'samples/server/petstore/kotlin-server/**'
- 'samples/server/petstore/kotlin-server-modelMutable/**'
@@ -34,6 +36,10 @@ jobs:
matrix:
sample:
# server
+ - samples/server/others/kotlin-server/polymorphism-allof-and-discriminator
+ - samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix
+ - samples/server/others/kotlin-server/polymorphism-and-discriminator
+ - samples/server/others/kotlin-server/polymorphism
- samples/server/petstore/kotlin-server-required-and-nullable-properties
- samples/server/petstore/kotlin-springboot-3
- samples/server/petstore/kotlin-springboot-3-no-response-entity
diff --git a/.github/workflows/samples-kotlin-server-jdk21.yaml b/.github/workflows/samples-kotlin-server-jdk21.yaml
index 5670620a4017..8d70d007e658 100644
--- a/.github/workflows/samples-kotlin-server-jdk21.yaml
+++ b/.github/workflows/samples-kotlin-server-jdk21.yaml
@@ -3,10 +3,12 @@ name: Samples Kotlin server (jdk21)
on:
push:
paths:
+ - 'samples/server/others/kotlin-server/**'
- 'samples/server/petstore/kotlin-server/**'
- 'samples/server/petstore/kotlin-server-required-and-nullable-properties/**'
pull_request:
paths:
+ - 'samples/server/others/kotlin-server/**'
- 'samples/server/petstore/kotlin-server/**'
- 'samples/server/petstore/kotlin-server-required-and-nullable-properties/**'
@@ -21,6 +23,10 @@ jobs:
fail-fast: false
matrix:
sample:
+ - samples/server/others/kotlin-server/polymorphism-allof-and-discriminator
+ - samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix
+ - samples/server/others/kotlin-server/polymorphism-and-discriminator
+ - samples/server/others/kotlin-server/polymorphism
- samples/server/petstore/kotlin-server/javalin-6
- samples/server/petstore/kotlin-server/ktor
- samples/server/petstore/kotlin-server/ktor2
diff --git a/bin/configs/kotlin-server-polymorphism-allof-and-discriminator.yaml b/bin/configs/kotlin-server-polymorphism-allof-and-discriminator.yaml
new file mode 100644
index 000000000000..bb97d8d6e786
--- /dev/null
+++ b/bin/configs/kotlin-server-polymorphism-allof-and-discriminator.yaml
@@ -0,0 +1,7 @@
+generatorName: kotlin-server
+outputDir: samples/server/others/kotlin-server/polymorphism-allof-and-discriminator
+inputSpec: modules/openapi-generator/src/test/resources/3_1/polymorphism-allof-and-discriminator.yaml
+templateDir: modules/openapi-generator/src/main/resources/kotlin-server
+additionalProperties:
+ artifactId: kotlin-server-polymorphism-allof-and-discriminator
+ library: javalin6
diff --git a/bin/configs/kotlin-server-polymorphism-and-discriminator-disabled-jackson-fix.yaml b/bin/configs/kotlin-server-polymorphism-and-discriminator-disabled-jackson-fix.yaml
new file mode 100644
index 000000000000..1b62aba2bee1
--- /dev/null
+++ b/bin/configs/kotlin-server-polymorphism-and-discriminator-disabled-jackson-fix.yaml
@@ -0,0 +1,10 @@
+generatorName: kotlin-server
+outputDir: samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix
+inputSpec: modules/openapi-generator/src/test/resources/3_1/polymorphism-and-discriminator.yaml
+templateDir: modules/openapi-generator/src/main/resources/kotlin-server
+additionalProperties:
+ artifactId: kotlin-server-polymorphism-and-discriminator-disabled-jackson-fix
+ library: javalin6
+ # This is set to "true" by default, but we also want to test the case where it's set to false.
+ # See KotlinServerCodegen.java for more details about this property.
+ fixJacksonJsonTypeInfoInheritance: false
diff --git a/bin/configs/kotlin-server-polymorphism-and-discriminator.yaml b/bin/configs/kotlin-server-polymorphism-and-discriminator.yaml
new file mode 100644
index 000000000000..3fc8b4623e04
--- /dev/null
+++ b/bin/configs/kotlin-server-polymorphism-and-discriminator.yaml
@@ -0,0 +1,8 @@
+generatorName: kotlin-server
+outputDir: samples/server/others/kotlin-server/polymorphism-and-discriminator
+inputSpec: modules/openapi-generator/src/test/resources/3_1/polymorphism-and-discriminator.yaml
+templateDir: modules/openapi-generator/src/main/resources/kotlin-server
+additionalProperties:
+ artifactId: kotlin-server-polymorphism-and-discriminator
+ library: javalin6
+ fixJacksonJsonTypeInfoInheritance: true
diff --git a/bin/configs/kotlin-server-polymorphism.yaml b/bin/configs/kotlin-server-polymorphism.yaml
new file mode 100644
index 000000000000..880cedd89d39
--- /dev/null
+++ b/bin/configs/kotlin-server-polymorphism.yaml
@@ -0,0 +1,7 @@
+generatorName: kotlin-server
+outputDir: samples/server/others/kotlin-server/polymorphism
+inputSpec: modules/openapi-generator/src/test/resources/3_1/polymorphism.yaml
+templateDir: modules/openapi-generator/src/main/resources/kotlin-server
+additionalProperties:
+ artifactId: kotlin-server-polymorphism
+ library: javalin6
diff --git a/docs/generators/kotlin-server.md b/docs/generators/kotlin-server.md
index 733e819e6ce3..86859ea27401 100644
--- a/docs/generators/kotlin-server.md
+++ b/docs/generators/kotlin-server.md
@@ -30,6 +30,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|featureHSTS|Avoid sending content if client already has same content, by checking ETag or LastModified properties.| |true|
|featureMetrics|Enables metrics feature.| |true|
|featureResources|Generates routes in a typed way, for both: constructing URLs and reading the parameters.| |true|
+|fixJacksonJsonTypeInfoInheritance|When true (default), ensures Jackson polymorphism works correctly by: (1) always setting visible=true on @JsonTypeInfo, and (2) adding the discriminator property to child models with appropriate default values. When false, visible is only set to true if all children already define the discriminator property.| |true|
|groupId|Generated artifact package's organization (i.e. maven groupId).| |org.openapitools|
|interfaceOnly|Whether to generate only API interface stubs without the server files. This option is currently supported only when using jaxrs-spec library.| |false|
|library|library template (sub-template)|
**ktor** ktor framework **ktor2** ktor (2.x) framework **jaxrs-spec** JAX-RS spec only **javalin5** Javalin 5 **javalin6** Javalin 6 |ktor|
@@ -262,11 +263,11 @@ These options may be applied as additional-properties (cli) or configOptions (pl
| ---- | --------- | ---------- |
|Simple|✓|OAS2,OAS3
|Composite|✓|OAS2,OAS3
-|Polymorphism|✗|OAS2,OAS3
+|Polymorphism|✓|OAS2,OAS3
|Union|✗|OAS3
-|allOf|✗|OAS2,OAS3
+|allOf|✓|OAS2,OAS3
|anyOf|✗|OAS3
-|oneOf|✗|OAS3
+|oneOf|✓|OAS3
|not|✗|OAS3
### Security Feature
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinServerCodegen.java
index fea7e9af79cd..06755794d42e 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinServerCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinServerCodegen.java
@@ -25,6 +25,7 @@
import org.openapitools.codegen.languages.features.BeanValidationFeatures;
import org.openapitools.codegen.meta.features.*;
import org.openapitools.codegen.model.ModelMap;
+import org.openapitools.codegen.model.ModelsMap;
import org.openapitools.codegen.model.OperationMap;
import org.openapitools.codegen.model.OperationsMap;
import org.openapitools.codegen.templating.mustache.CamelCaseLambda;
@@ -68,6 +69,9 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen implements BeanVa
private boolean returnResponse = false;
@Setter
private boolean omitGradleWrapper = false;
+ @Getter
+ @Setter
+ private boolean fixJacksonJsonTypeInfoInheritance = true;
// This is here to potentially warn the user when an option is not supported by the target framework.
private Map> optionsSupportedPerFramework = new ImmutableMap.Builder>()
@@ -106,6 +110,9 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen implements BeanVa
public KotlinServerCodegen() {
super();
+ // Enable proper oneOf/anyOf discriminator handling for polymorphism
+ legacyDiscriminatorBehavior = false;
+
modifyFeatureSet(features -> features
.includeDocumentationFeatures(DocumentationFeature.Readme)
.wireFormatFeatures(EnumSet.of(WireFormatFeature.JSON, WireFormatFeature.XML))
@@ -120,7 +127,9 @@ public KotlinServerCodegen() {
GlobalFeature.LinkObjects,
GlobalFeature.ParameterStyling
)
- .excludeSchemaSupportFeatures(
+ .includeSchemaSupportFeatures(
+ SchemaSupportFeature.allOf,
+ SchemaSupportFeature.oneOf,
SchemaSupportFeature.Polymorphism
)
.excludeParameterFeatures(
@@ -166,6 +175,7 @@ public KotlinServerCodegen() {
addSwitch(Constants.RETURN_RESPONSE, Constants.RETURN_RESPONSE_DESC, returnResponse);
addSwitch(Constants.OMIT_GRADLE_WRAPPER, Constants.OMIT_GRADLE_WRAPPER_DESC, omitGradleWrapper);
addSwitch(USE_JAKARTA_EE, Constants.USE_JAKARTA_EE_DESC, useJakartaEe);
+ addSwitch(Constants.FIX_JACKSON_JSON_TYPE_INFO_INHERITANCE, Constants.FIX_JACKSON_JSON_TYPE_INFO_INHERITANCE_DESC, fixJacksonJsonTypeInfoInheritance);
}
@Override
@@ -235,6 +245,11 @@ public void processOpts() {
setOmitGradleWrapper(Boolean.parseBoolean(additionalProperties.get(Constants.OMIT_GRADLE_WRAPPER).toString()));
}
+ if (additionalProperties.containsKey(Constants.FIX_JACKSON_JSON_TYPE_INFO_INHERITANCE)) {
+ setFixJacksonJsonTypeInfoInheritance(Boolean.parseBoolean(additionalProperties.get(Constants.FIX_JACKSON_JSON_TYPE_INFO_INHERITANCE).toString()));
+ }
+ additionalProperties.put(Constants.FIX_JACKSON_JSON_TYPE_INFO_INHERITANCE, fixJacksonJsonTypeInfoInheritance);
+
writePropertyBack(USE_BEANVALIDATION, useBeanValidation);
// set default library to "ktor"
@@ -381,6 +396,291 @@ public static class Constants {
public static final String OMIT_GRADLE_WRAPPER = "omitGradleWrapper";
public static final String OMIT_GRADLE_WRAPPER_DESC = "Whether to omit Gradle wrapper for creating a sub project.";
public static final String IS_KTOR = "isKtor";
+ public static final String FIX_JACKSON_JSON_TYPE_INFO_INHERITANCE = "fixJacksonJsonTypeInfoInheritance";
+ public static final String FIX_JACKSON_JSON_TYPE_INFO_INHERITANCE_DESC = "When true (default), ensures Jackson polymorphism works correctly by: (1) always setting visible=true on @JsonTypeInfo, and (2) adding the discriminator property to child models with appropriate default values. When false, visible is only set to true if all children already define the discriminator property.";
+ }
+
+ @Override
+ public Map postProcessAllModels(Map objs) {
+ objs = super.postProcessAllModels(objs);
+
+ // For libraries that use Jackson, set up parent-child relationships for discriminator children
+ // This enables proper polymorphism support with @JsonTypeInfo and @JsonSubTypes annotations
+ if (usesJacksonSerialization()) {
+ // Build a map of model name -> model for easy lookup
+ Map allModelsMap = new HashMap<>();
+ for (ModelsMap modelsMap : objs.values()) {
+ for (ModelMap modelMap : modelsMap.getModels()) {
+ CodegenModel model = modelMap.getModel();
+ allModelsMap.put(model.getClassname(), model);
+ }
+ }
+
+ // First pass: collect all discriminator parent -> children mappings
+ // Also identify the "true" discriminator owners (not inherited via allOf)
+ Map childToParentMap = new HashMap<>();
+ Set trueDiscriminatorOwners = new HashSet<>();
+
+ for (ModelsMap modelsMap : objs.values()) {
+ for (ModelMap modelMap : modelsMap.getModels()) {
+ CodegenModel model = modelMap.getModel();
+ if (model.getDiscriminator() != null && model.getDiscriminator().getMappedModels() != null
+ && !model.getDiscriminator().getMappedModels().isEmpty()) {
+ String discriminatorPropBaseName = model.getDiscriminator().getPropertyBaseName();
+
+ for (CodegenDiscriminator.MappedModel mappedModel : model.getDiscriminator().getMappedModels()) {
+ childToParentMap.put(mappedModel.getModelName(), model.getClassname());
+
+ // If the mapping name equals the model name, check if we can derive
+ // a better mapping name from the child's discriminator property enum value
+ if (mappedModel.getMappingName().equals(mappedModel.getModelName())) {
+ CodegenModel childModel = allModelsMap.get(mappedModel.getModelName());
+ if (childModel != null) {
+ // Find the discriminator property in the child model
+ for (CodegenProperty prop : childModel.getAllVars()) {
+ if (prop.getBaseName().equals(discriminatorPropBaseName) && prop.isEnum) {
+ // If it's an enum with exactly one value, use that as the mapping name
+ Map allowableValues = prop.getAllowableValues();
+ if (allowableValues != null && allowableValues.containsKey("values")) {
+ @SuppressWarnings("unchecked")
+ List values = (List) allowableValues.get("values");
+ if (values != null && values.size() == 1) {
+ mappedModel.setMappingName(String.valueOf(values.get(0)));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ // This model owns its discriminator (has mapped models)
+ trueDiscriminatorOwners.add(model.getClassname());
+ }
+ }
+ }
+
+ // Second pass: process child models
+ for (ModelsMap modelsMap : objs.values()) {
+ for (ModelMap modelMap : modelsMap.getModels()) {
+ CodegenModel model = modelMap.getModel();
+ String parentName = childToParentMap.get(model.getClassname());
+
+ if (parentName != null) {
+ // This model is a child of a discriminator parent
+ CodegenModel parentModel = allModelsMap.get(parentName);
+
+ // Set parent if not already set
+ if (model.getParent() == null) {
+ model.setParent(parentName);
+ }
+
+ // If this child has a discriminator but it's inherited (not a true owner),
+ // remove it - only the parent should have the discriminator annotations
+ if (model.getDiscriminator() != null && !trueDiscriminatorOwners.contains(model.getClassname())) {
+ model.setDiscriminator(null);
+ }
+
+ // For allOf pattern: if parent has properties, mark child's inherited properties
+ // Skip this for oneOf/anyOf patterns where parent properties are merged from children
+ boolean parentIsOneOfOrAnyOf = parentModel != null
+ && ((parentModel.oneOf != null && !parentModel.oneOf.isEmpty())
+ || (parentModel.anyOf != null && !parentModel.anyOf.isEmpty()));
+
+ if (parentModel != null && parentModel.getHasVars() && !parentIsOneOfOrAnyOf) {
+ Set parentPropNames = new HashSet<>();
+ List inheritedPropNamesList = new ArrayList<>();
+ for (CodegenProperty parentProp : parentModel.getAllVars()) {
+ parentPropNames.add(parentProp.getBaseName());
+ inheritedPropNamesList.add(parentProp.getName());
+ }
+
+ // Mark properties inherited from parent
+ for (CodegenProperty prop : model.getAllVars()) {
+ if (parentPropNames.contains(prop.getBaseName())) {
+ prop.isInherited = true;
+ }
+ }
+ for (CodegenProperty prop : model.getVars()) {
+ if (parentPropNames.contains(prop.getBaseName())) {
+ prop.isInherited = true;
+ }
+ }
+ for (CodegenProperty prop : model.getRequiredVars()) {
+ if (parentPropNames.contains(prop.getBaseName())) {
+ prop.isInherited = true;
+ }
+ }
+ for (CodegenProperty prop : model.getOptionalVars()) {
+ if (parentPropNames.contains(prop.getBaseName())) {
+ prop.isInherited = true;
+ }
+ }
+
+ // Set vendor extension for parent constructor call with inherited properties
+ if (!inheritedPropNamesList.isEmpty()) {
+ String parentCtorArgs = String.join(", ", inheritedPropNamesList.stream()
+ .map(name -> name + " = " + name)
+ .toArray(String[]::new));
+ model.getVendorExtensions().put("x-parent-ctor-args", parentCtorArgs);
+ }
+ }
+ }
+ }
+ }
+
+ // Third pass: set vendor extension for discriminator style and handle fixJacksonJsonTypeInfoInheritance
+ for (String ownerName : trueDiscriminatorOwners) {
+ CodegenModel owner = allModelsMap.get(ownerName);
+ if (owner != null && owner.getDiscriminator() != null) {
+ String discriminatorPropBaseName = owner.getDiscriminator().getPropertyBaseName();
+ boolean isOneOfOrAnyOfPattern = (owner.oneOf != null && !owner.oneOf.isEmpty())
+ || (owner.anyOf != null && !owner.anyOf.isEmpty());
+
+ // hasParentProperties controls whether the sealed class has properties in its constructor
+ // This should be false for oneOf/anyOf patterns (parent is a type union, no direct properties)
+ // and true for allOf patterns (parent has properties that children inherit)
+ boolean hasParentProperties = !isOneOfOrAnyOfPattern;
+
+ // visibleTrue controls whether visible=true is set on @JsonTypeInfo
+ // When fixJacksonJsonTypeInfoInheritance is true, we always set visible=true
+ // When false, we only set visible=true if the parent has properties (allOf pattern)
+ boolean visibleTrue;
+
+ if (fixJacksonJsonTypeInfoInheritance) {
+ // When fixJacksonJsonTypeInfoInheritance is true:
+ // 1. Always set visible=true so Jackson can read the discriminator
+ // 2. For oneOf/anyOf patterns: add discriminator property to parent and children
+ visibleTrue = true;
+
+ // For oneOf/anyOf patterns, add the discriminator property to the parent sealed class
+ // This allows accessing the discriminator value from the parent type directly
+ if (isOneOfOrAnyOfPattern) {
+ String discriminatorVarName = toVarName(discriminatorPropBaseName);
+
+ // Clear all merged properties from the oneOf parent - they belong to children only
+ // We'll add back just the discriminator property
+ owner.getVars().clear();
+ owner.getRequiredVars().clear();
+ owner.getOptionalVars().clear();
+ owner.getAllVars().clear();
+
+ // Add discriminator property to parent
+ CodegenProperty parentDiscriminatorProp = new CodegenProperty();
+ parentDiscriminatorProp.baseName = discriminatorPropBaseName;
+ parentDiscriminatorProp.name = discriminatorVarName;
+ parentDiscriminatorProp.dataType = "kotlin.String";
+ parentDiscriminatorProp.datatypeWithEnum = "kotlin.String";
+ parentDiscriminatorProp.required = true;
+ parentDiscriminatorProp.isNullable = false;
+ parentDiscriminatorProp.isReadOnly = false;
+
+ owner.getVars().add(parentDiscriminatorProp);
+ owner.getRequiredVars().add(parentDiscriminatorProp);
+ owner.getAllVars().add(parentDiscriminatorProp);
+
+ // Parent now has properties (just the discriminator)
+ hasParentProperties = true;
+
+ // Process children: mark discriminator as inherited and set default values
+ for (CodegenDiscriminator.MappedModel mappedModel : owner.getDiscriminator().getMappedModels()) {
+ CodegenModel childModel = allModelsMap.get(mappedModel.getModelName());
+ if (childModel != null) {
+ boolean hasDiscriminatorProp = false;
+ String discriminatorDefault = "\"" + mappedModel.getMappingName() + "\"";
+
+ // Update existing discriminator property in all lists - mark as inherited
+ for (CodegenProperty prop : childModel.getVars()) {
+ if (prop.getBaseName().equals(discriminatorPropBaseName)) {
+ hasDiscriminatorProp = true;
+ prop.defaultValue = discriminatorDefault;
+ prop.dataType = "kotlin.String";
+ prop.datatypeWithEnum = "kotlin.String";
+ prop.required = true;
+ prop.isNullable = false;
+ prop.isInherited = true;
+ }
+ }
+ for (CodegenProperty prop : childModel.getAllVars()) {
+ if (prop.getBaseName().equals(discriminatorPropBaseName)) {
+ prop.defaultValue = discriminatorDefault;
+ prop.dataType = "kotlin.String";
+ prop.datatypeWithEnum = "kotlin.String";
+ prop.required = true;
+ prop.isNullable = false;
+ prop.isInherited = true;
+ }
+ }
+
+ // Move discriminator from optionalVars to requiredVars if needed
+ CodegenProperty propToMove = null;
+ for (CodegenProperty prop : childModel.getOptionalVars()) {
+ if (prop.getBaseName().equals(discriminatorPropBaseName)) {
+ prop.defaultValue = discriminatorDefault;
+ prop.dataType = "kotlin.String";
+ prop.datatypeWithEnum = "kotlin.String";
+ prop.required = true;
+ prop.isNullable = false;
+ prop.isInherited = true;
+ propToMove = prop;
+ break;
+ }
+ }
+ if (propToMove != null) {
+ childModel.getOptionalVars().remove(propToMove);
+ childModel.getRequiredVars().add(propToMove);
+ }
+
+ // Also update if it's already in requiredVars
+ for (CodegenProperty prop : childModel.getRequiredVars()) {
+ if (prop.getBaseName().equals(discriminatorPropBaseName)) {
+ prop.defaultValue = discriminatorDefault;
+ prop.dataType = "kotlin.String";
+ prop.datatypeWithEnum = "kotlin.String";
+ prop.isNullable = false;
+ prop.isInherited = true;
+ }
+ }
+
+ // If child doesn't have the discriminator property, add it as required and inherited
+ if (!hasDiscriminatorProp) {
+ CodegenProperty discriminatorProp = new CodegenProperty();
+ discriminatorProp.baseName = discriminatorPropBaseName;
+ discriminatorProp.name = discriminatorVarName;
+ discriminatorProp.dataType = "kotlin.String";
+ discriminatorProp.datatypeWithEnum = "kotlin.String";
+ discriminatorProp.defaultValue = discriminatorDefault;
+ discriminatorProp.required = true;
+ discriminatorProp.isNullable = false;
+ discriminatorProp.isReadOnly = false;
+ discriminatorProp.isInherited = true;
+
+ childModel.getVars().add(discriminatorProp);
+ childModel.getRequiredVars().add(discriminatorProp);
+ childModel.getAllVars().add(discriminatorProp);
+ }
+
+ // Set parent constructor args for the discriminator property
+ childModel.getVendorExtensions().put("x-parent-ctor-args",
+ discriminatorVarName + " = " + discriminatorVarName);
+ }
+ }
+ }
+ } else {
+ // When fixJacksonJsonTypeInfoInheritance is false:
+ // visible=true only for allOf pattern (parent has properties)
+ visibleTrue = hasParentProperties;
+ }
+
+ // Set on both model and discriminator so it's accessible in different template contexts
+ owner.getVendorExtensions().put("x-discriminator-has-parent-properties", hasParentProperties);
+ owner.getDiscriminator().getVendorExtensions().put("x-discriminator-has-parent-properties", hasParentProperties);
+ owner.getVendorExtensions().put("x-discriminator-visible-true", visibleTrue);
+ owner.getDiscriminator().getVendorExtensions().put("x-discriminator-visible-true", visibleTrue);
+ }
+ }
+ }
+
+ return objs;
}
@Override
@@ -462,6 +762,16 @@ private boolean isJavalin() {
return Constants.JAVALIN5.equals(library) || Constants.JAVALIN6.equals(library);
}
+ /**
+ * Returns true if the current library uses Jackson for JSON serialization.
+ * This is used to determine if Jackson-specific features like polymorphism annotations should be enabled.
+ */
+ private boolean usesJacksonSerialization() {
+ return Constants.JAVALIN5.equals(library) ||
+ Constants.JAVALIN6.equals(library) ||
+ Constants.JAXRS_SPEC.equals(library);
+ }
+
private boolean isKtor2Or3() {
return Constants.KTOR.equals(library) || Constants.KTOR2.equals(library);
}
diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/data_class.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/data_class.mustache
index d7c41d201e97..2318e574e45b 100644
--- a/modules/openapi-generator/src/main/resources/kotlin-server/data_class.mustache
+++ b/modules/openapi-generator/src/main/resources/kotlin-server/data_class.mustache
@@ -12,23 +12,86 @@ import java.io.Serializable
{{/isKtor}}
/**
* {{{description}}}
+{{#isKtor}}
+{{#vars}}
+ * @param {{{name}}} {{{description}}}
+{{/vars}}
+{{/isKtor}}
+{{^isKtor}}
+{{^discriminator}}
{{#vars}}
* @param {{{name}}} {{{description}}}
{{/vars}}
+{{/discriminator}}
+{{#discriminator}}
+{{#vendorExtensions.x-discriminator-has-parent-properties}}
+{{#vars}}
+ * @param {{{name}}} {{{description}}}
+{{/vars}}
+{{/vendorExtensions.x-discriminator-has-parent-properties}}
+{{/discriminator}}
+{{/isKtor}}
*/
{{#parcelizeModels}}
@Parcelize
{{/parcelizeModels}}
{{#isKtor}}
@Serializable
+{{#hasVars}}data {{/hasVars}}class {{classname}}(
+{{#requiredVars}}
+{{>data_class_req_var}}{{^-last}},
+{{/-last}}{{/requiredVars}}{{#hasRequired}}{{#hasOptional}},
+{{/hasOptional}}{{/hasRequired}}{{#optionalVars}}{{>data_class_opt_var}}{{^-last}},
+{{/-last}}{{/optionalVars}}
+)
+{{#vendorExtensions.x-has-data-class-body}}
+{
+{{/vendorExtensions.x-has-data-class-body}}
+{{#hasEnums}}
+ {{#vars}}
+ {{#isEnum}}
+ /**
+ * {{{description}}}
+ * Values: {{#allowableValues}}{{#enumVars}}{{&name}}{{^-last}},{{/-last}}{{/enumVars}}{{/allowableValues}}
+ */
+ enum class {{{nameInPascalCase}}}(val value: {{{dataType}}}){
+ {{#allowableValues}}
+ {{#enumVars}}
+ {{&name}}({{{value}}}){{^-last}},{{/-last}}{{#-last}};{{/-last}}
+ {{/enumVars}}
+ {{/allowableValues}}
+ }
+{{/isEnum}}
+{{/vars}}
+{{/hasEnums}}
+{{#vendorExtensions.x-has-data-class-body}}
+}
+{{/vendorExtensions.x-has-data-class-body}}
{{/isKtor}}
+{{^isKtor}}
+{{#discriminator}}
+{{>typeInfoAnnotation}}
+{{#vendorExtensions.x-discriminator-has-parent-properties}}
+sealed class {{classname}}(
+{{#requiredVars}}
+{{>data_class_sealed_var}}{{^-last}},
+{{/-last}}{{/requiredVars}}{{#hasRequired}}{{#hasOptional}},
+{{/hasOptional}}{{/hasRequired}}{{#optionalVars}}{{>data_class_sealed_var}}{{^-last}},
+{{/-last}}{{/optionalVars}}
+)
+{{/vendorExtensions.x-discriminator-has-parent-properties}}
+{{^vendorExtensions.x-discriminator-has-parent-properties}}
+sealed class {{classname}}
+{{/vendorExtensions.x-discriminator-has-parent-properties}}
+{{/discriminator}}
+{{^discriminator}}
{{#hasVars}}data {{/hasVars}}class {{classname}}(
{{#requiredVars}}
{{>data_class_req_var}}{{^-last}},
{{/-last}}{{/requiredVars}}{{#hasRequired}}{{#hasOptional}},
{{/hasOptional}}{{/hasRequired}}{{#optionalVars}}{{>data_class_opt_var}}{{^-last}},
{{/-last}}{{/optionalVars}}
-){{^isKtor}}{{^serializableModel}}{{#parcelizeModels}} : Parcelable{{/parcelizeModels}}{{/serializableModel}}{{^parcelizeModels}}{{#serializableModel}}: Serializable {{/serializableModel}}{{/parcelizeModels}}{{#parcelizeModels}}{{#serializableModel}} : Parcelable, Serializable {{/serializableModel}}{{/parcelizeModels}}{{/isKtor}}
+){{#parent}} : {{{.}}}({{#vendorExtensions.x-parent-ctor-args}}{{{.}}}{{/vendorExtensions.x-parent-ctor-args}}){{/parent}}{{^parent}}{{^serializableModel}}{{#parcelizeModels}} : Parcelable{{/parcelizeModels}}{{/serializableModel}}{{^parcelizeModels}}{{#serializableModel}}: Serializable {{/serializableModel}}{{/parcelizeModels}}{{#parcelizeModels}}{{#serializableModel}} : Parcelable, Serializable {{/serializableModel}}{{/parcelizeModels}}{{/parent}}
{{#vendorExtensions.x-has-data-class-body}}
{
{{/vendorExtensions.x-has-data-class-body}}
@@ -52,3 +115,5 @@ import java.io.Serializable
{{#vendorExtensions.x-has-data-class-body}}
}
{{/vendorExtensions.x-has-data-class-body}}
+{{/discriminator}}
+{{/isKtor}}
diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/data_class_interface_var.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/data_class_interface_var.mustache
new file mode 100644
index 000000000000..38f8ce582237
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/kotlin-server/data_class_interface_var.mustache
@@ -0,0 +1,4 @@
+{{#description}}
+ /* {{{.}}} */
+{{/description}}
+ open val {{{name}}}: {{#isEnum}}{{{classname}}}.{{{nameInPascalCase}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#isNullable}}?{{/isNullable}}{{^isNullable}}{{^required}}?{{/required}}{{/isNullable}}{{#defaultValue}} = {{^isNumber}}{{{defaultValue}}}{{/isNumber}}{{#isNumber}}{{{dataType}}}("{{{defaultValue}}}"){{/isNumber}}{{/defaultValue}}{{^defaultValue}}{{^required}} = null{{/required}}{{/defaultValue}}
diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/data_class_sealed_var.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/data_class_sealed_var.mustache
new file mode 100644
index 000000000000..432546d708fc
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/kotlin-server/data_class_sealed_var.mustache
@@ -0,0 +1,6 @@
+{{#description}}
+ /* {{{.}}} */
+{{/description}}
+ {{#useBeanValidation}}{{>beanValidation}}{{>beanValidationModel}}{{/useBeanValidation}}
+ @field:com.fasterxml.jackson.annotation.JsonProperty("{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}")
+ open {{>modelMutable}} {{{name}}}: {{#isEnum}}{{{classname}}}.{{{nameInPascalCase}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#isNullable}}?{{/isNullable}}{{#defaultValue}} = {{^isNumber}}{{{defaultValue}}}{{/isNumber}}{{#isNumber}}{{{dataType}}}("{{{defaultValue}}}"){{/isNumber}}{{/defaultValue}}
diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/data_class_opt_var.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/data_class_opt_var.mustache
index dfbcaafa2062..684077c31410 100644
--- a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/data_class_opt_var.mustache
+++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/data_class_opt_var.mustache
@@ -3,4 +3,4 @@
{{/description}}
{{#useBeanValidation}}{{>beanValidation}}{{>beanValidationModel}}{{/useBeanValidation}}
@field:com.fasterxml.jackson.annotation.JsonProperty("{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}")
- {{>modelMutable}} {{{name}}}: {{#isEnum}}{{{classname}}}.{{{nameInPascalCase}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}? = {{{defaultValue}}}{{^defaultValue}}null{{/defaultValue}}
\ No newline at end of file
+ {{#isInherited}}override {{/isInherited}}{{>modelMutable}} {{{name}}}: {{#isEnum}}{{{classname}}}.{{{nameInPascalCase}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}? = {{{defaultValue}}}{{^defaultValue}}null{{/defaultValue}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/data_class_req_var.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/data_class_req_var.mustache
index 94bf2e8d24b5..f8c518ff8c05 100644
--- a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/data_class_req_var.mustache
+++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/data_class_req_var.mustache
@@ -3,4 +3,4 @@
{{/description}}
{{#useBeanValidation}}{{>beanValidation}}{{>beanValidationModel}}{{/useBeanValidation}}
@field:com.fasterxml.jackson.annotation.JsonProperty("{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}")
- {{>modelMutable}} {{{name}}}: {{#isEnum}}{{{classname}}}.{{{nameInPascalCase}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#isNullable}}?{{/isNullable}}{{#defaultValue}} = {{^isNumber}}{{{defaultValue}}}{{/isNumber}}{{#isNumber}}{{{dataType}}}("{{{defaultValue}}}"){{/isNumber}}{{/defaultValue}}
\ No newline at end of file
+ {{#isInherited}}override {{/isInherited}}{{>modelMutable}} {{{name}}}: {{#isEnum}}{{{classname}}}.{{{nameInPascalCase}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#isNullable}}?{{/isNullable}}{{#defaultValue}} = {{^isNumber}}{{{defaultValue}}}{{/isNumber}}{{#isNumber}}{{{dataType}}}("{{{defaultValue}}}"){{/isNumber}}{{/defaultValue}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/data_class_sealed_var.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/data_class_sealed_var.mustache
new file mode 100644
index 000000000000..432546d708fc
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin5/data_class_sealed_var.mustache
@@ -0,0 +1,6 @@
+{{#description}}
+ /* {{{.}}} */
+{{/description}}
+ {{#useBeanValidation}}{{>beanValidation}}{{>beanValidationModel}}{{/useBeanValidation}}
+ @field:com.fasterxml.jackson.annotation.JsonProperty("{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}")
+ open {{>modelMutable}} {{{name}}}: {{#isEnum}}{{{classname}}}.{{{nameInPascalCase}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#isNullable}}?{{/isNullable}}{{#defaultValue}} = {{^isNumber}}{{{defaultValue}}}{{/isNumber}}{{#isNumber}}{{{dataType}}}("{{{defaultValue}}}"){{/isNumber}}{{/defaultValue}}
diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/data_class_interface_var.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/data_class_interface_var.mustache
new file mode 100644
index 000000000000..05b193378680
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/data_class_interface_var.mustache
@@ -0,0 +1,5 @@
+{{#description}}
+ /* {{{.}}} */
+{{/description}}
+ @get:com.fasterxml.jackson.annotation.JsonProperty("{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}")
+ open val {{{name}}}: {{#isEnum}}{{{classname}}}.{{{nameInPascalCase}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#isNullable}}?{{/isNullable}}{{^isNullable}}{{^required}}?{{/required}}{{/isNullable}}{{#defaultValue}} = {{^isNumber}}{{{defaultValue}}}{{/isNumber}}{{#isNumber}}{{{dataType}}}("{{{defaultValue}}}"){{/isNumber}}{{/defaultValue}}{{^defaultValue}}{{^required}} = null{{/required}}{{/defaultValue}}
diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/data_class_opt_var.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/data_class_opt_var.mustache
index dfbcaafa2062..684077c31410 100644
--- a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/data_class_opt_var.mustache
+++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/data_class_opt_var.mustache
@@ -3,4 +3,4 @@
{{/description}}
{{#useBeanValidation}}{{>beanValidation}}{{>beanValidationModel}}{{/useBeanValidation}}
@field:com.fasterxml.jackson.annotation.JsonProperty("{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}")
- {{>modelMutable}} {{{name}}}: {{#isEnum}}{{{classname}}}.{{{nameInPascalCase}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}? = {{{defaultValue}}}{{^defaultValue}}null{{/defaultValue}}
\ No newline at end of file
+ {{#isInherited}}override {{/isInherited}}{{>modelMutable}} {{{name}}}: {{#isEnum}}{{{classname}}}.{{{nameInPascalCase}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}? = {{{defaultValue}}}{{^defaultValue}}null{{/defaultValue}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/data_class_req_var.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/data_class_req_var.mustache
index 94bf2e8d24b5..f8c518ff8c05 100644
--- a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/data_class_req_var.mustache
+++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/data_class_req_var.mustache
@@ -3,4 +3,4 @@
{{/description}}
{{#useBeanValidation}}{{>beanValidation}}{{>beanValidationModel}}{{/useBeanValidation}}
@field:com.fasterxml.jackson.annotation.JsonProperty("{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}")
- {{>modelMutable}} {{{name}}}: {{#isEnum}}{{{classname}}}.{{{nameInPascalCase}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#isNullable}}?{{/isNullable}}{{#defaultValue}} = {{^isNumber}}{{{defaultValue}}}{{/isNumber}}{{#isNumber}}{{{dataType}}}("{{{defaultValue}}}"){{/isNumber}}{{/defaultValue}}
\ No newline at end of file
+ {{#isInherited}}override {{/isInherited}}{{>modelMutable}} {{{name}}}: {{#isEnum}}{{{classname}}}.{{{nameInPascalCase}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#isNullable}}?{{/isNullable}}{{#defaultValue}} = {{^isNumber}}{{{defaultValue}}}{{/isNumber}}{{#isNumber}}{{{dataType}}}("{{{defaultValue}}}"){{/isNumber}}{{/defaultValue}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/data_class_sealed_var.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/data_class_sealed_var.mustache
new file mode 100644
index 000000000000..432546d708fc
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/javalin6/data_class_sealed_var.mustache
@@ -0,0 +1,6 @@
+{{#description}}
+ /* {{{.}}} */
+{{/description}}
+ {{#useBeanValidation}}{{>beanValidation}}{{>beanValidationModel}}{{/useBeanValidation}}
+ @field:com.fasterxml.jackson.annotation.JsonProperty("{{#lambda.escapeDollar}}{{baseName}}{{/lambda.escapeDollar}}")
+ open {{>modelMutable}} {{{name}}}: {{#isEnum}}{{{classname}}}.{{{nameInPascalCase}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#isNullable}}?{{/isNullable}}{{#defaultValue}} = {{^isNumber}}{{{defaultValue}}}{{/isNumber}}{{#isNumber}}{{{dataType}}}("{{{defaultValue}}}"){{/isNumber}}{{/defaultValue}}
diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/typeInfoAnnotation.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/typeInfoAnnotation.mustache
new file mode 100644
index 000000000000..88fddd2d51cb
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/kotlin-server/typeInfoAnnotation.mustache
@@ -0,0 +1,6 @@
+@com.fasterxml.jackson.annotation.JsonTypeInfo(use = com.fasterxml.jackson.annotation.JsonTypeInfo.Id.NAME, include = com.fasterxml.jackson.annotation.JsonTypeInfo.As.PROPERTY, property = "{{{discriminator.propertyBaseName}}}", visible = {{#vendorExtensions.x-discriminator-visible-true}}true{{/vendorExtensions.x-discriminator-visible-true}}{{^vendorExtensions.x-discriminator-visible-true}}false{{/vendorExtensions.x-discriminator-visible-true}})
+@com.fasterxml.jackson.annotation.JsonSubTypes(
+{{#discriminator.mappedModels}}
+ com.fasterxml.jackson.annotation.JsonSubTypes.Type(value = {{modelName}}::class, name = "{{^vendorExtensions.x-discriminator-value}}{{mappingName}}{{/vendorExtensions.x-discriminator-value}}{{#vendorExtensions.x-discriminator-value}}{{{vendorExtensions.x-discriminator-value}}}{{/vendorExtensions.x-discriminator-value}}"){{^-last}},{{/-last}}
+{{/discriminator.mappedModels}}
+)
diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinServerCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinServerCodegenTest.java
index 7f74dc145c1e..0850466701e1 100644
--- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinServerCodegenTest.java
+++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinServerCodegenTest.java
@@ -35,7 +35,6 @@
public class KotlinServerCodegenTest {
-
@Test
public void enumDescription() throws IOException {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
@@ -311,4 +310,203 @@ public void givenSchemaObjectPropertyNameContainsDollarSignWhenGenerateThenDolla
Assert.assertTrue(syntaxErrorListener.getSyntaxErrorCount() == 0);
Assert.assertTrue(customKotlinParseListener.getStringReferenceCount() == 0);
}
+
+ // ==================== Polymorphism and Discriminator Tests ====================
+
+ @Test
+ public void oneOfWithDiscriminator_generatesSealedClassWithDiscriminatorProperty() throws IOException {
+ File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
+ output.deleteOnExit();
+
+ KotlinServerCodegen codegen = new KotlinServerCodegen();
+ codegen.setOutputDir(output.getAbsolutePath());
+ codegen.additionalProperties().put(LIBRARY, JAVALIN6);
+
+ new DefaultGenerator().opts(new ClientOptInput()
+ .openAPI(TestUtils.parseSpec("src/test/resources/3_1/polymorphism-and-discriminator.yaml"))
+ .config(codegen))
+ .generate();
+
+ String outputPath = output.getAbsolutePath() + "/src/main/kotlin/org/openapitools/server";
+ Path petModel = Paths.get(outputPath + "/models/Pet.kt");
+
+ // Pet should be a sealed class with Jackson polymorphism annotations and discriminator property
+ assertFileContains(
+ petModel,
+ "sealed class Pet(",
+ "open val petType: kotlin.String",
+ "@com.fasterxml.jackson.annotation.JsonTypeInfo",
+ "property = \"petType\"",
+ "visible = true",
+ "@com.fasterxml.jackson.annotation.JsonSubTypes"
+ );
+ }
+
+ @Test
+ public void oneOfWithDiscriminator_generatesChildrenWithOverrideDiscriminatorProperty() throws IOException {
+ File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
+ output.deleteOnExit();
+
+ KotlinServerCodegen codegen = new KotlinServerCodegen();
+ codegen.setOutputDir(output.getAbsolutePath());
+ codegen.additionalProperties().put(LIBRARY, JAVALIN6);
+
+ new DefaultGenerator().opts(new ClientOptInput()
+ .openAPI(TestUtils.parseSpec("src/test/resources/3_1/polymorphism-and-discriminator.yaml"))
+ .config(codegen))
+ .generate();
+
+ String outputPath = output.getAbsolutePath() + "/src/main/kotlin/org/openapitools/server";
+
+ // Cat should have petType as overridden non-nullable String with default value
+ Path catModel = Paths.get(outputPath + "/models/Cat.kt");
+ assertFileContains(
+ catModel,
+ "data class Cat(",
+ "override val petType: kotlin.String = \"cat\"",
+ ") : Pet(petType = petType)"
+ );
+ // Should NOT be nullable
+ assertFileNotContains(
+ catModel,
+ "petType: kotlin.String?",
+ "petType: kotlin.Any"
+ );
+
+ // Dog should have petType as overridden non-nullable String with default value
+ Path dogModel = Paths.get(outputPath + "/models/Dog.kt");
+ assertFileContains(
+ dogModel,
+ "data class Dog(",
+ "override val petType: kotlin.String = \"dog\"",
+ ") : Pet(petType = petType)"
+ );
+ // Should NOT be nullable
+ assertFileNotContains(
+ dogModel,
+ "petType: kotlin.String?",
+ "petType: kotlin.Any"
+ );
+ }
+
+ @Test
+ public void allOfWithDiscriminator_generatesSealedClassWithProperties() throws IOException {
+ File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
+ output.deleteOnExit();
+
+ KotlinServerCodegen codegen = new KotlinServerCodegen();
+ codegen.setOutputDir(output.getAbsolutePath());
+ codegen.additionalProperties().put(LIBRARY, JAVALIN6);
+
+ new DefaultGenerator().opts(new ClientOptInput()
+ .openAPI(TestUtils.parseSpec("src/test/resources/3_1/polymorphism-allof-and-discriminator.yaml"))
+ .config(codegen))
+ .generate();
+
+ String outputPath = output.getAbsolutePath() + "/src/main/kotlin/org/openapitools/server";
+ Path petModel = Paths.get(outputPath + "/models/Pet.kt");
+
+ // Pet should be a sealed class WITH properties (allOf pattern)
+ assertFileContains(
+ petModel,
+ "sealed class Pet(",
+ "open val name: kotlin.String",
+ "open val petType: kotlin.String",
+ "@com.fasterxml.jackson.annotation.JsonTypeInfo",
+ "visible = true"
+ );
+ }
+
+ @Test
+ public void allOfWithDiscriminator_generatesChildrenWithOverrideProperties() throws IOException {
+ File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
+ output.deleteOnExit();
+
+ KotlinServerCodegen codegen = new KotlinServerCodegen();
+ codegen.setOutputDir(output.getAbsolutePath());
+ codegen.additionalProperties().put(LIBRARY, JAVALIN6);
+
+ new DefaultGenerator().opts(new ClientOptInput()
+ .openAPI(TestUtils.parseSpec("src/test/resources/3_1/polymorphism-allof-and-discriminator.yaml"))
+ .config(codegen))
+ .generate();
+
+ String outputPath = output.getAbsolutePath() + "/src/main/kotlin/org/openapitools/server";
+
+ // Cat should use override for inherited properties and pass them to parent constructor
+ Path catModel = Paths.get(outputPath + "/models/Cat.kt");
+ assertFileContains(
+ catModel,
+ "data class Cat(",
+ "override val name: kotlin.String",
+ "override val petType: kotlin.String",
+ ") : Pet(name = name, petType = petType)"
+ );
+
+ // Dog should use override for inherited properties and pass them to parent constructor
+ Path dogModel = Paths.get(outputPath + "/models/Dog.kt");
+ assertFileContains(
+ dogModel,
+ "data class Dog(",
+ "override val name: kotlin.String",
+ "override val petType: kotlin.String",
+ ") : Pet(name = name, petType = petType)"
+ );
+ }
+
+ @Test
+ public void polymorphismWithoutDiscriminator_generatesRegularDataClass() throws IOException {
+ File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
+ output.deleteOnExit();
+
+ KotlinServerCodegen codegen = new KotlinServerCodegen();
+ codegen.setOutputDir(output.getAbsolutePath());
+ codegen.additionalProperties().put(LIBRARY, JAVALIN6);
+
+ new DefaultGenerator().opts(new ClientOptInput()
+ .openAPI(TestUtils.parseSpec("src/test/resources/3_1/polymorphism.yaml"))
+ .config(codegen))
+ .generate();
+
+ String outputPath = output.getAbsolutePath() + "/src/main/kotlin/org/openapitools/server";
+ Path petModel = Paths.get(outputPath + "/models/Pet.kt");
+
+ // Without discriminator, Pet should be a regular data class (not sealed)
+ assertFileContains(
+ petModel,
+ "data class Pet("
+ );
+ assertFileNotContains(
+ petModel,
+ "sealed class",
+ "@com.fasterxml.jackson.annotation.JsonTypeInfo",
+ "@com.fasterxml.jackson.annotation.JsonSubTypes"
+ );
+ }
+
+ @Test
+ public void fixJacksonJsonTypeInfoInheritance_canBeDisabled() throws IOException {
+ File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
+ output.deleteOnExit();
+
+ KotlinServerCodegen codegen = new KotlinServerCodegen();
+ codegen.setOutputDir(output.getAbsolutePath());
+ codegen.additionalProperties().put(LIBRARY, JAVALIN6);
+ codegen.additionalProperties().put(KotlinServerCodegen.Constants.FIX_JACKSON_JSON_TYPE_INFO_INHERITANCE, false);
+
+ new DefaultGenerator().opts(new ClientOptInput()
+ .openAPI(TestUtils.parseSpec("src/test/resources/3_1/polymorphism-and-discriminator.yaml"))
+ .config(codegen))
+ .generate();
+
+ String outputPath = output.getAbsolutePath() + "/src/main/kotlin/org/openapitools/server";
+ Path petModel = Paths.get(outputPath + "/models/Pet.kt");
+
+ // When fixJacksonJsonTypeInfoInheritance is false and parent has no properties,
+ // visible should be false for oneOf pattern
+ assertFileContains(
+ petModel,
+ "visible = false"
+ );
+ }
}
diff --git a/modules/openapi-generator/src/test/resources/3_1/polymorphism-allof-and-discriminator.yaml b/modules/openapi-generator/src/test/resources/3_1/polymorphism-allof-and-discriminator.yaml
new file mode 100644
index 000000000000..8c9ab49297f8
--- /dev/null
+++ b/modules/openapi-generator/src/test/resources/3_1/polymorphism-allof-and-discriminator.yaml
@@ -0,0 +1,52 @@
+# https://spec.openapis.org/oas/v3.2.0.html#models-with-polymorphism-support-using-allof-and-a-discriminator-object
+# 4.24.8.9 Models with Polymorphism Support using allOf and a Discriminator Object
+# It is also possible to describe polymorphic models using allOf. The following example uses allOf with a Discriminator Object to describe a polymorphic Pet model.
+openapi: 3.1.0
+info:
+ title: Polymorphism example with allOf and discriminator
+ version: "1.0"
+paths: {}
+components:
+ schemas:
+ Pet:
+ type: object
+ discriminator:
+ propertyName: petType
+ properties:
+ name:
+ type: string
+ petType:
+ type: string
+ required:
+ - name
+ - petType
+ Cat: # "Cat" will be used as the discriminating value
+ description: A representation of a cat
+ allOf:
+ - $ref: '#/components/schemas/Pet'
+ - type: object
+ properties:
+ huntingSkill:
+ type: string
+ description: The measured skill for hunting
+ enum:
+ - clueless
+ - lazy
+ - adventurous
+ - aggressive
+ required:
+ - huntingSkill
+ Dog: # "Dog" will be used as the discriminating value
+ description: A representation of a dog
+ allOf:
+ - $ref: '#/components/schemas/Pet'
+ - type: object
+ properties:
+ packSize:
+ type: integer
+ format: int32
+ description: the size of the pack the dog is from
+ default: 0
+ minimum: 0
+ required:
+ - packSize
\ No newline at end of file
diff --git a/modules/openapi-generator/src/test/resources/3_1/polymorphism-and-discriminator.yaml b/modules/openapi-generator/src/test/resources/3_1/polymorphism-and-discriminator.yaml
new file mode 100644
index 000000000000..66de012640ef
--- /dev/null
+++ b/modules/openapi-generator/src/test/resources/3_1/polymorphism-and-discriminator.yaml
@@ -0,0 +1,57 @@
+# https://spec.openapis.org/oas/v3.2.0.html#models-with-polymorphism-support-and-a-discriminator-object
+# 4.24.8.8 Models with Polymorphism Support and a Discriminator Object
+# The following example extends the example of the previous section by adding a Discriminator Object to the Pet schema. Note that the Discriminator Object is only a hint to the consumer of the API and does not change the validation outcome of the schema.
+openapi: 3.1.0
+info:
+ title: Basic polymorphism example with discriminator
+ version: "1.0"
+paths: {}
+components:
+ schemas:
+ Pet:
+ type: object
+ discriminator:
+ propertyName: petType
+ mapping:
+ cat: '#/components/schemas/Cat'
+ dog: '#/components/schemas/Dog'
+ properties:
+ name:
+ type: string
+ required:
+ - name
+ - petType
+ oneOf:
+ - $ref: '#/components/schemas/Cat'
+ - $ref: '#/components/schemas/Dog'
+ Cat:
+ description: A pet cat
+ type: object
+ properties:
+ petType:
+ const: 'cat'
+ huntingSkill:
+ type: string
+ description: The measured skill for hunting
+ enum:
+ - clueless
+ - lazy
+ - adventurous
+ - aggressive
+ required:
+ - huntingSkill
+ Dog:
+ description: A pet dog
+ type: object
+ properties:
+ petType:
+ const: 'dog'
+ packSize:
+ type: integer
+ format: int32
+ description: the size of the pack the dog is from
+ default: 0
+ minimum: 0
+ required:
+ - petType
+ - packSize
\ No newline at end of file
diff --git a/modules/openapi-generator/src/test/resources/3_1/polymorphism.yaml b/modules/openapi-generator/src/test/resources/3_1/polymorphism.yaml
new file mode 100644
index 000000000000..0bf42ac99957
--- /dev/null
+++ b/modules/openapi-generator/src/test/resources/3_1/polymorphism.yaml
@@ -0,0 +1,50 @@
+# https://spec.openapis.org/oas/v3.2.0.html#models-with-polymorphism-support
+# 4.24.8.7 Models with Polymorphism Support
+# The following example describes a Pet model that can represent either a cat or a dog, as distinguished by the petType property. Each type of pet has other properties beyond those of the base Pet model. An instance without a petType property, or with a petType property that does not match either cat or dog, is invalid.
+openapi: 3.1.0
+info:
+ title: Basic polymorphism example without discriminator
+ version: "1.0"
+components:
+ schemas:
+ Pet:
+ type: object
+ properties:
+ name:
+ type: string
+ required:
+ - name
+ - petType
+ oneOf:
+ - $ref: '#/components/schemas/Cat'
+ - $ref: '#/components/schemas/Dog'
+ Cat:
+ description: A pet cat
+ type: object
+ properties:
+ petType:
+ const: 'cat'
+ huntingSkill:
+ type: string
+ description: The measured skill for hunting
+ enum:
+ - clueless
+ - lazy
+ - adventurous
+ - aggressive
+ required:
+ - huntingSkill
+ Dog:
+ description: A pet dog
+ type: object
+ properties:
+ petType:
+ const: 'dog'
+ packSize:
+ type: integer
+ format: int32
+ description: the size of the pack the dog is from
+ default: 0
+ minimum: 0
+ required:
+ - packSize
\ No newline at end of file
diff --git a/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/.openapi-generator-ignore b/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/.openapi-generator-ignore
new file mode 100644
index 000000000000..7484ee590a38
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/.openapi-generator-ignore
@@ -0,0 +1,23 @@
+# OpenAPI Generator Ignore
+# Generated by openapi-generator https://github.com/openapitools/openapi-generator
+
+# Use this file to prevent files from being overwritten by the generator.
+# The patterns follow closely to .gitignore or .dockerignore.
+
+# As an example, the C# client generator defines ApiClient.cs.
+# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
+#ApiClient.cs
+
+# You can match any string of characters against a directory, file or extension with a single asterisk (*):
+#foo/*/qux
+# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
+
+# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
+#foo/**/qux
+# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
+
+# You can also negate patterns with an exclamation (!).
+# For example, you can ignore all files in a docs folder with the file extension .md:
+#docs/*.md
+# Then explicitly reverse the ignore rule for a single file:
+#!docs/README.md
diff --git a/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/.openapi-generator/FILES b/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/.openapi-generator/FILES
new file mode 100644
index 000000000000..339ec9249554
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/.openapi-generator/FILES
@@ -0,0 +1,8 @@
+README.md
+build.gradle.kts
+gradle.properties
+settings.gradle
+src/main/kotlin/org/openapitools/server/Main.kt
+src/main/kotlin/org/openapitools/server/models/Cat.kt
+src/main/kotlin/org/openapitools/server/models/Dog.kt
+src/main/kotlin/org/openapitools/server/models/Pet.kt
diff --git a/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/.openapi-generator/VERSION b/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/.openapi-generator/VERSION
new file mode 100644
index 000000000000..909dcd0eca63
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/.openapi-generator/VERSION
@@ -0,0 +1 @@
+7.19.0-SNAPSHOT
diff --git a/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/README.md b/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/README.md
new file mode 100644
index 000000000000..b87573de7f39
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/README.md
@@ -0,0 +1,61 @@
+# org.openapitools.server - Kotlin Server library for Polymorphism example with allOf and discriminator
+
+No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
+
+Generated by OpenAPI Generator 7.19.0-SNAPSHOT.
+
+## Build
+
+First, create the gradle wrapper script:
+
+```
+gradle wrapper
+```
+
+Then, run:
+
+```
+./gradlew check assemble
+```
+
+This runs all tests and packages the library.
+
+## Running
+
+The server builds as a fat jar with a main entrypoint. To start the service, run `java -jar ./build/libs/kotlin-server-polymorphism-allof-and-discriminator.jar`.
+
+You may also run in docker:
+
+```
+docker build -t kotlin-server-polymorphism-allof-and-discriminator .
+docker run -p 8080:8080 kotlin-server-polymorphism-allof-and-discriminator
+```
+
+## Features/Implementation Notes
+
+* Supports JSON inputs/outputs, File inputs, and Form inputs (see ktor documentation for more info).
+* ~Supports collection formats for query parameters: csv, tsv, ssv, pipes.~
+* Some Kotlin and Java types are fully qualified to avoid conflicts with types defined in OpenAPI definitions.
+
+
+## Documentation for API Endpoints
+
+All URIs are relative to *http://localhost*
+
+Class | Method | HTTP request | Description
+------------ | ------------- | ------------- | -------------
+
+
+
+## Documentation for Models
+
+ - [org.openapitools.server.models.Cat](docs/Cat.md)
+ - [org.openapitools.server.models.Dog](docs/Dog.md)
+ - [org.openapitools.server.models.Pet](docs/Pet.md)
+
+
+
+## Documentation for Authorization
+
+Endpoints do not require authorization.
+
diff --git a/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/build.gradle.kts b/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/build.gradle.kts
new file mode 100644
index 000000000000..220ec0c53ac7
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/build.gradle.kts
@@ -0,0 +1,33 @@
+plugins {
+ kotlin("jvm") version "2.0.21"
+}
+
+group = "org.openapitools"
+version = "1.0.0"
+
+kotlin {
+ jvmToolchain(21)
+}
+
+java {
+ toolchain {
+ languageVersion.set(JavaLanguageVersion.of(21))
+ }
+}
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ implementation("io.javalin:javalin:6.1.6")
+ implementation("com.fasterxml.jackson.core:jackson-databind:2.17.1")
+ implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.17.1")
+ implementation("org.slf4j:slf4j-simple:2.0.13")
+
+ testImplementation("org.jetbrains.kotlin:kotlin-test")
+}
+
+tasks.test {
+ useJUnitPlatform()
+}
diff --git a/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/gradle.properties b/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/gradle.properties
new file mode 100644
index 000000000000..5f1ed7bbe024
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/gradle.properties
@@ -0,0 +1 @@
+org.gradle.caching=true
\ No newline at end of file
diff --git a/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/settings.gradle b/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/settings.gradle
new file mode 100644
index 000000000000..71f8d7d6439a
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/settings.gradle
@@ -0,0 +1 @@
+rootProject.name = 'kotlin-server-polymorphism-allof-and-discriminator'
\ No newline at end of file
diff --git a/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/src/main/kotlin/org/openapitools/server/Main.kt b/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/src/main/kotlin/org/openapitools/server/Main.kt
new file mode 100644
index 000000000000..dba7f137ec60
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/src/main/kotlin/org/openapitools/server/Main.kt
@@ -0,0 +1,16 @@
+package org.openapitools.server
+
+import io.javalin.Javalin
+import io.javalin.apibuilder.ApiBuilder.*
+
+
+fun main() {
+
+ val app = Javalin
+ .create { config ->
+ config.router.apiBuilder {
+ }
+ }
+
+ app.start()
+}
diff --git a/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/src/main/kotlin/org/openapitools/server/models/Cat.kt b/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/src/main/kotlin/org/openapitools/server/models/Cat.kt
new file mode 100644
index 000000000000..e9e835517bae
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/src/main/kotlin/org/openapitools/server/models/Cat.kt
@@ -0,0 +1,44 @@
+/**
+ * Polymorphism example with allOf and discriminator
+ * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
+ *
+ * The version of the OpenAPI document: 1.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+*/
+package org.openapitools.server.models
+
+import org.openapitools.server.models.Pet
+
+/**
+ * A representation of a cat
+ * @param huntingSkill The measured skill for hunting
+ */
+data class Cat(
+ /* The measured skill for hunting */
+
+ @field:com.fasterxml.jackson.annotation.JsonProperty("huntingSkill")
+ val huntingSkill: Cat.HuntingSkill,
+
+ @field:com.fasterxml.jackson.annotation.JsonProperty("name")
+ override val name: kotlin.String,
+
+ @field:com.fasterxml.jackson.annotation.JsonProperty("petType")
+ override val petType: kotlin.String
+) : Pet(name = name, petType = petType)
+{
+ /**
+ * The measured skill for hunting
+ * Values: clueless,lazy,adventurous,aggressive
+ */
+ enum class HuntingSkill(val value: kotlin.String){
+ clueless("clueless"),
+ lazy("lazy"),
+ adventurous("adventurous"),
+ aggressive("aggressive");
+ }
+}
+
diff --git a/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/src/main/kotlin/org/openapitools/server/models/Dog.kt b/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/src/main/kotlin/org/openapitools/server/models/Dog.kt
new file mode 100644
index 000000000000..4066cb7a51f8
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/src/main/kotlin/org/openapitools/server/models/Dog.kt
@@ -0,0 +1,34 @@
+/**
+ * Polymorphism example with allOf and discriminator
+ * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
+ *
+ * The version of the OpenAPI document: 1.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+*/
+package org.openapitools.server.models
+
+import org.openapitools.server.models.Pet
+
+/**
+ * A representation of a dog
+ * @param packSize the size of the pack the dog is from
+ */
+data class Dog(
+ /* the size of the pack the dog is from */
+
+ @field:com.fasterxml.jackson.annotation.JsonProperty("packSize")
+ val packSize: kotlin.Int = 0,
+
+ @field:com.fasterxml.jackson.annotation.JsonProperty("name")
+ override val name: kotlin.String,
+
+ @field:com.fasterxml.jackson.annotation.JsonProperty("petType")
+ override val petType: kotlin.String
+) : Pet(name = name, petType = petType)
+{
+}
+
diff --git a/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/src/main/kotlin/org/openapitools/server/models/Pet.kt b/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/src/main/kotlin/org/openapitools/server/models/Pet.kt
new file mode 100644
index 000000000000..5812ac1944eb
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/src/main/kotlin/org/openapitools/server/models/Pet.kt
@@ -0,0 +1,35 @@
+/**
+ * Polymorphism example with allOf and discriminator
+ * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
+ *
+ * The version of the OpenAPI document: 1.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+*/
+package org.openapitools.server.models
+
+
+/**
+ *
+ * @param name
+ * @param petType
+ */
+@com.fasterxml.jackson.annotation.JsonTypeInfo(use = com.fasterxml.jackson.annotation.JsonTypeInfo.Id.NAME, include = com.fasterxml.jackson.annotation.JsonTypeInfo.As.PROPERTY, property = "petType", visible = true)
+@com.fasterxml.jackson.annotation.JsonSubTypes(
+ com.fasterxml.jackson.annotation.JsonSubTypes.Type(value = Cat::class, name = "Cat"),
+ com.fasterxml.jackson.annotation.JsonSubTypes.Type(value = Dog::class, name = "Dog")
+)
+sealed class Pet(
+
+ @field:com.fasterxml.jackson.annotation.JsonProperty("name")
+ open val name: kotlin.String
+,
+
+ @field:com.fasterxml.jackson.annotation.JsonProperty("petType")
+ open val petType: kotlin.String
+
+)
+
diff --git a/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/.openapi-generator-ignore b/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/.openapi-generator-ignore
new file mode 100644
index 000000000000..7484ee590a38
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/.openapi-generator-ignore
@@ -0,0 +1,23 @@
+# OpenAPI Generator Ignore
+# Generated by openapi-generator https://github.com/openapitools/openapi-generator
+
+# Use this file to prevent files from being overwritten by the generator.
+# The patterns follow closely to .gitignore or .dockerignore.
+
+# As an example, the C# client generator defines ApiClient.cs.
+# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
+#ApiClient.cs
+
+# You can match any string of characters against a directory, file or extension with a single asterisk (*):
+#foo/*/qux
+# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
+
+# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
+#foo/**/qux
+# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
+
+# You can also negate patterns with an exclamation (!).
+# For example, you can ignore all files in a docs folder with the file extension .md:
+#docs/*.md
+# Then explicitly reverse the ignore rule for a single file:
+#!docs/README.md
diff --git a/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/.openapi-generator/FILES b/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/.openapi-generator/FILES
new file mode 100644
index 000000000000..339ec9249554
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/.openapi-generator/FILES
@@ -0,0 +1,8 @@
+README.md
+build.gradle.kts
+gradle.properties
+settings.gradle
+src/main/kotlin/org/openapitools/server/Main.kt
+src/main/kotlin/org/openapitools/server/models/Cat.kt
+src/main/kotlin/org/openapitools/server/models/Dog.kt
+src/main/kotlin/org/openapitools/server/models/Pet.kt
diff --git a/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/.openapi-generator/VERSION b/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/.openapi-generator/VERSION
new file mode 100644
index 000000000000..909dcd0eca63
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/.openapi-generator/VERSION
@@ -0,0 +1 @@
+7.19.0-SNAPSHOT
diff --git a/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/README.md b/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/README.md
new file mode 100644
index 000000000000..fce0a6d57580
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/README.md
@@ -0,0 +1,61 @@
+# org.openapitools.server - Kotlin Server library for Basic polymorphism example with discriminator
+
+No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
+
+Generated by OpenAPI Generator 7.19.0-SNAPSHOT.
+
+## Build
+
+First, create the gradle wrapper script:
+
+```
+gradle wrapper
+```
+
+Then, run:
+
+```
+./gradlew check assemble
+```
+
+This runs all tests and packages the library.
+
+## Running
+
+The server builds as a fat jar with a main entrypoint. To start the service, run `java -jar ./build/libs/kotlin-server-polymorphism-and-discriminator-disabled-jackson-fix.jar`.
+
+You may also run in docker:
+
+```
+docker build -t kotlin-server-polymorphism-and-discriminator-disabled-jackson-fix .
+docker run -p 8080:8080 kotlin-server-polymorphism-and-discriminator-disabled-jackson-fix
+```
+
+## Features/Implementation Notes
+
+* Supports JSON inputs/outputs, File inputs, and Form inputs (see ktor documentation for more info).
+* ~Supports collection formats for query parameters: csv, tsv, ssv, pipes.~
+* Some Kotlin and Java types are fully qualified to avoid conflicts with types defined in OpenAPI definitions.
+
+
+## Documentation for API Endpoints
+
+All URIs are relative to *http://localhost*
+
+Class | Method | HTTP request | Description
+------------ | ------------- | ------------- | -------------
+
+
+
+## Documentation for Models
+
+ - [org.openapitools.server.models.Cat](docs/Cat.md)
+ - [org.openapitools.server.models.Dog](docs/Dog.md)
+ - [org.openapitools.server.models.Pet](docs/Pet.md)
+
+
+
+## Documentation for Authorization
+
+Endpoints do not require authorization.
+
diff --git a/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/build.gradle.kts b/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/build.gradle.kts
new file mode 100644
index 000000000000..220ec0c53ac7
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/build.gradle.kts
@@ -0,0 +1,33 @@
+plugins {
+ kotlin("jvm") version "2.0.21"
+}
+
+group = "org.openapitools"
+version = "1.0.0"
+
+kotlin {
+ jvmToolchain(21)
+}
+
+java {
+ toolchain {
+ languageVersion.set(JavaLanguageVersion.of(21))
+ }
+}
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ implementation("io.javalin:javalin:6.1.6")
+ implementation("com.fasterxml.jackson.core:jackson-databind:2.17.1")
+ implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.17.1")
+ implementation("org.slf4j:slf4j-simple:2.0.13")
+
+ testImplementation("org.jetbrains.kotlin:kotlin-test")
+}
+
+tasks.test {
+ useJUnitPlatform()
+}
diff --git a/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/gradle.properties b/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/gradle.properties
new file mode 100644
index 000000000000..5f1ed7bbe024
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/gradle.properties
@@ -0,0 +1 @@
+org.gradle.caching=true
\ No newline at end of file
diff --git a/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/settings.gradle b/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/settings.gradle
new file mode 100644
index 000000000000..afbefa9d3e72
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/settings.gradle
@@ -0,0 +1 @@
+rootProject.name = 'kotlin-server-polymorphism-and-discriminator-disabled-jackson-fix'
\ No newline at end of file
diff --git a/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/src/main/kotlin/org/openapitools/server/Main.kt b/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/src/main/kotlin/org/openapitools/server/Main.kt
new file mode 100644
index 000000000000..dba7f137ec60
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/src/main/kotlin/org/openapitools/server/Main.kt
@@ -0,0 +1,16 @@
+package org.openapitools.server
+
+import io.javalin.Javalin
+import io.javalin.apibuilder.ApiBuilder.*
+
+
+fun main() {
+
+ val app = Javalin
+ .create { config ->
+ config.router.apiBuilder {
+ }
+ }
+
+ app.start()
+}
diff --git a/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/src/main/kotlin/org/openapitools/server/models/Cat.kt b/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/src/main/kotlin/org/openapitools/server/models/Cat.kt
new file mode 100644
index 000000000000..dd82367937fe
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/src/main/kotlin/org/openapitools/server/models/Cat.kt
@@ -0,0 +1,41 @@
+/**
+ * Basic polymorphism example with discriminator
+ * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
+ *
+ * The version of the OpenAPI document: 1.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+*/
+package org.openapitools.server.models
+
+
+/**
+ * A pet cat
+ * @param huntingSkill The measured skill for hunting
+ * @param petType
+ */
+data class Cat(
+ /* The measured skill for hunting */
+
+ @field:com.fasterxml.jackson.annotation.JsonProperty("huntingSkill")
+ val huntingSkill: Cat.HuntingSkill,
+
+ @field:com.fasterxml.jackson.annotation.JsonProperty("petType")
+ val petType: kotlin.Any? = null
+) : Pet()
+{
+ /**
+ * The measured skill for hunting
+ * Values: clueless,lazy,adventurous,aggressive
+ */
+ enum class HuntingSkill(val value: kotlin.String){
+ clueless("clueless"),
+ lazy("lazy"),
+ adventurous("adventurous"),
+ aggressive("aggressive");
+ }
+}
+
diff --git a/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/src/main/kotlin/org/openapitools/server/models/Dog.kt b/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/src/main/kotlin/org/openapitools/server/models/Dog.kt
new file mode 100644
index 000000000000..1360130bed0a
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/src/main/kotlin/org/openapitools/server/models/Dog.kt
@@ -0,0 +1,29 @@
+/**
+ * Basic polymorphism example with discriminator
+ * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
+ *
+ * The version of the OpenAPI document: 1.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+*/
+package org.openapitools.server.models
+
+
+/**
+ * A pet dog
+ * @param petType
+ * @param packSize the size of the pack the dog is from
+ */
+data class Dog(
+
+ @field:com.fasterxml.jackson.annotation.JsonProperty("petType")
+ val petType: kotlin.Any?,
+ /* the size of the pack the dog is from */
+
+ @field:com.fasterxml.jackson.annotation.JsonProperty("packSize")
+ val packSize: kotlin.Int = 0
+) : Pet()
+
diff --git a/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/src/main/kotlin/org/openapitools/server/models/Pet.kt b/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/src/main/kotlin/org/openapitools/server/models/Pet.kt
new file mode 100644
index 000000000000..b2c3ac1d7be4
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/src/main/kotlin/org/openapitools/server/models/Pet.kt
@@ -0,0 +1,26 @@
+/**
+ * Basic polymorphism example with discriminator
+ * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
+ *
+ * The version of the OpenAPI document: 1.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+*/
+package org.openapitools.server.models
+
+import org.openapitools.server.models.Cat
+import org.openapitools.server.models.Dog
+
+/**
+ *
+ */
+@com.fasterxml.jackson.annotation.JsonTypeInfo(use = com.fasterxml.jackson.annotation.JsonTypeInfo.Id.NAME, include = com.fasterxml.jackson.annotation.JsonTypeInfo.As.PROPERTY, property = "petType", visible = false)
+@com.fasterxml.jackson.annotation.JsonSubTypes(
+ com.fasterxml.jackson.annotation.JsonSubTypes.Type(value = Cat::class, name = "cat"),
+ com.fasterxml.jackson.annotation.JsonSubTypes.Type(value = Dog::class, name = "dog")
+)
+sealed class Pet
+
diff --git a/samples/server/others/kotlin-server/polymorphism-and-discriminator/.openapi-generator-ignore b/samples/server/others/kotlin-server/polymorphism-and-discriminator/.openapi-generator-ignore
new file mode 100644
index 000000000000..7484ee590a38
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-and-discriminator/.openapi-generator-ignore
@@ -0,0 +1,23 @@
+# OpenAPI Generator Ignore
+# Generated by openapi-generator https://github.com/openapitools/openapi-generator
+
+# Use this file to prevent files from being overwritten by the generator.
+# The patterns follow closely to .gitignore or .dockerignore.
+
+# As an example, the C# client generator defines ApiClient.cs.
+# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
+#ApiClient.cs
+
+# You can match any string of characters against a directory, file or extension with a single asterisk (*):
+#foo/*/qux
+# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
+
+# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
+#foo/**/qux
+# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
+
+# You can also negate patterns with an exclamation (!).
+# For example, you can ignore all files in a docs folder with the file extension .md:
+#docs/*.md
+# Then explicitly reverse the ignore rule for a single file:
+#!docs/README.md
diff --git a/samples/server/others/kotlin-server/polymorphism-and-discriminator/.openapi-generator/FILES b/samples/server/others/kotlin-server/polymorphism-and-discriminator/.openapi-generator/FILES
new file mode 100644
index 000000000000..339ec9249554
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-and-discriminator/.openapi-generator/FILES
@@ -0,0 +1,8 @@
+README.md
+build.gradle.kts
+gradle.properties
+settings.gradle
+src/main/kotlin/org/openapitools/server/Main.kt
+src/main/kotlin/org/openapitools/server/models/Cat.kt
+src/main/kotlin/org/openapitools/server/models/Dog.kt
+src/main/kotlin/org/openapitools/server/models/Pet.kt
diff --git a/samples/server/others/kotlin-server/polymorphism-and-discriminator/.openapi-generator/VERSION b/samples/server/others/kotlin-server/polymorphism-and-discriminator/.openapi-generator/VERSION
new file mode 100644
index 000000000000..909dcd0eca63
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-and-discriminator/.openapi-generator/VERSION
@@ -0,0 +1 @@
+7.19.0-SNAPSHOT
diff --git a/samples/server/others/kotlin-server/polymorphism-and-discriminator/README.md b/samples/server/others/kotlin-server/polymorphism-and-discriminator/README.md
new file mode 100644
index 000000000000..f1c177f47b5f
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-and-discriminator/README.md
@@ -0,0 +1,61 @@
+# org.openapitools.server - Kotlin Server library for Basic polymorphism example with discriminator
+
+No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
+
+Generated by OpenAPI Generator 7.19.0-SNAPSHOT.
+
+## Build
+
+First, create the gradle wrapper script:
+
+```
+gradle wrapper
+```
+
+Then, run:
+
+```
+./gradlew check assemble
+```
+
+This runs all tests and packages the library.
+
+## Running
+
+The server builds as a fat jar with a main entrypoint. To start the service, run `java -jar ./build/libs/kotlin-server-polymorphism-and-discriminator.jar`.
+
+You may also run in docker:
+
+```
+docker build -t kotlin-server-polymorphism-and-discriminator .
+docker run -p 8080:8080 kotlin-server-polymorphism-and-discriminator
+```
+
+## Features/Implementation Notes
+
+* Supports JSON inputs/outputs, File inputs, and Form inputs (see ktor documentation for more info).
+* ~Supports collection formats for query parameters: csv, tsv, ssv, pipes.~
+* Some Kotlin and Java types are fully qualified to avoid conflicts with types defined in OpenAPI definitions.
+
+
+## Documentation for API Endpoints
+
+All URIs are relative to *http://localhost*
+
+Class | Method | HTTP request | Description
+------------ | ------------- | ------------- | -------------
+
+
+
+## Documentation for Models
+
+ - [org.openapitools.server.models.Cat](docs/Cat.md)
+ - [org.openapitools.server.models.Dog](docs/Dog.md)
+ - [org.openapitools.server.models.Pet](docs/Pet.md)
+
+
+
+## Documentation for Authorization
+
+Endpoints do not require authorization.
+
diff --git a/samples/server/others/kotlin-server/polymorphism-and-discriminator/build.gradle.kts b/samples/server/others/kotlin-server/polymorphism-and-discriminator/build.gradle.kts
new file mode 100644
index 000000000000..220ec0c53ac7
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-and-discriminator/build.gradle.kts
@@ -0,0 +1,33 @@
+plugins {
+ kotlin("jvm") version "2.0.21"
+}
+
+group = "org.openapitools"
+version = "1.0.0"
+
+kotlin {
+ jvmToolchain(21)
+}
+
+java {
+ toolchain {
+ languageVersion.set(JavaLanguageVersion.of(21))
+ }
+}
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ implementation("io.javalin:javalin:6.1.6")
+ implementation("com.fasterxml.jackson.core:jackson-databind:2.17.1")
+ implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.17.1")
+ implementation("org.slf4j:slf4j-simple:2.0.13")
+
+ testImplementation("org.jetbrains.kotlin:kotlin-test")
+}
+
+tasks.test {
+ useJUnitPlatform()
+}
diff --git a/samples/server/others/kotlin-server/polymorphism-and-discriminator/gradle.properties b/samples/server/others/kotlin-server/polymorphism-and-discriminator/gradle.properties
new file mode 100644
index 000000000000..5f1ed7bbe024
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-and-discriminator/gradle.properties
@@ -0,0 +1 @@
+org.gradle.caching=true
\ No newline at end of file
diff --git a/samples/server/others/kotlin-server/polymorphism-and-discriminator/settings.gradle b/samples/server/others/kotlin-server/polymorphism-and-discriminator/settings.gradle
new file mode 100644
index 000000000000..389e9ee99628
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-and-discriminator/settings.gradle
@@ -0,0 +1 @@
+rootProject.name = 'kotlin-server-polymorphism-and-discriminator'
\ No newline at end of file
diff --git a/samples/server/others/kotlin-server/polymorphism-and-discriminator/src/main/kotlin/org/openapitools/server/Main.kt b/samples/server/others/kotlin-server/polymorphism-and-discriminator/src/main/kotlin/org/openapitools/server/Main.kt
new file mode 100644
index 000000000000..dba7f137ec60
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-and-discriminator/src/main/kotlin/org/openapitools/server/Main.kt
@@ -0,0 +1,16 @@
+package org.openapitools.server
+
+import io.javalin.Javalin
+import io.javalin.apibuilder.ApiBuilder.*
+
+
+fun main() {
+
+ val app = Javalin
+ .create { config ->
+ config.router.apiBuilder {
+ }
+ }
+
+ app.start()
+}
diff --git a/samples/server/others/kotlin-server/polymorphism-and-discriminator/src/main/kotlin/org/openapitools/server/models/Cat.kt b/samples/server/others/kotlin-server/polymorphism-and-discriminator/src/main/kotlin/org/openapitools/server/models/Cat.kt
new file mode 100644
index 000000000000..99ab4e0f3f50
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-and-discriminator/src/main/kotlin/org/openapitools/server/models/Cat.kt
@@ -0,0 +1,42 @@
+/**
+ * Basic polymorphism example with discriminator
+ * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
+ *
+ * The version of the OpenAPI document: 1.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+*/
+package org.openapitools.server.models
+
+
+/**
+ * A pet cat
+ * @param huntingSkill The measured skill for hunting
+ * @param petType
+ */
+data class Cat(
+ /* The measured skill for hunting */
+
+ @field:com.fasterxml.jackson.annotation.JsonProperty("huntingSkill")
+ val huntingSkill: Cat.HuntingSkill,
+
+ @field:com.fasterxml.jackson.annotation.JsonProperty("petType")
+ override val petType: kotlin.String = "cat",
+
+) : Pet(petType = petType)
+{
+ /**
+ * The measured skill for hunting
+ * Values: clueless,lazy,adventurous,aggressive
+ */
+ enum class HuntingSkill(val value: kotlin.String){
+ clueless("clueless"),
+ lazy("lazy"),
+ adventurous("adventurous"),
+ aggressive("aggressive");
+ }
+}
+
diff --git a/samples/server/others/kotlin-server/polymorphism-and-discriminator/src/main/kotlin/org/openapitools/server/models/Dog.kt b/samples/server/others/kotlin-server/polymorphism-and-discriminator/src/main/kotlin/org/openapitools/server/models/Dog.kt
new file mode 100644
index 000000000000..9f3cbe860d93
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-and-discriminator/src/main/kotlin/org/openapitools/server/models/Dog.kt
@@ -0,0 +1,29 @@
+/**
+ * Basic polymorphism example with discriminator
+ * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
+ *
+ * The version of the OpenAPI document: 1.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+*/
+package org.openapitools.server.models
+
+
+/**
+ * A pet dog
+ * @param petType
+ * @param packSize the size of the pack the dog is from
+ */
+data class Dog(
+
+ @field:com.fasterxml.jackson.annotation.JsonProperty("petType")
+ override val petType: kotlin.String = "dog",
+ /* the size of the pack the dog is from */
+
+ @field:com.fasterxml.jackson.annotation.JsonProperty("packSize")
+ val packSize: kotlin.Int = 0
+) : Pet(petType = petType)
+
diff --git a/samples/server/others/kotlin-server/polymorphism-and-discriminator/src/main/kotlin/org/openapitools/server/models/Pet.kt b/samples/server/others/kotlin-server/polymorphism-and-discriminator/src/main/kotlin/org/openapitools/server/models/Pet.kt
new file mode 100644
index 000000000000..1311dc6d56ff
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism-and-discriminator/src/main/kotlin/org/openapitools/server/models/Pet.kt
@@ -0,0 +1,32 @@
+/**
+ * Basic polymorphism example with discriminator
+ * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
+ *
+ * The version of the OpenAPI document: 1.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+*/
+package org.openapitools.server.models
+
+import org.openapitools.server.models.Cat
+import org.openapitools.server.models.Dog
+
+/**
+ *
+ * @param petType
+ */
+@com.fasterxml.jackson.annotation.JsonTypeInfo(use = com.fasterxml.jackson.annotation.JsonTypeInfo.Id.NAME, include = com.fasterxml.jackson.annotation.JsonTypeInfo.As.PROPERTY, property = "petType", visible = true)
+@com.fasterxml.jackson.annotation.JsonSubTypes(
+ com.fasterxml.jackson.annotation.JsonSubTypes.Type(value = Cat::class, name = "cat"),
+ com.fasterxml.jackson.annotation.JsonSubTypes.Type(value = Dog::class, name = "dog")
+)
+sealed class Pet(
+
+ @field:com.fasterxml.jackson.annotation.JsonProperty("petType")
+ open val petType: kotlin.String
+
+)
+
diff --git a/samples/server/others/kotlin-server/polymorphism/.openapi-generator-ignore b/samples/server/others/kotlin-server/polymorphism/.openapi-generator-ignore
new file mode 100644
index 000000000000..7484ee590a38
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism/.openapi-generator-ignore
@@ -0,0 +1,23 @@
+# OpenAPI Generator Ignore
+# Generated by openapi-generator https://github.com/openapitools/openapi-generator
+
+# Use this file to prevent files from being overwritten by the generator.
+# The patterns follow closely to .gitignore or .dockerignore.
+
+# As an example, the C# client generator defines ApiClient.cs.
+# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
+#ApiClient.cs
+
+# You can match any string of characters against a directory, file or extension with a single asterisk (*):
+#foo/*/qux
+# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
+
+# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
+#foo/**/qux
+# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
+
+# You can also negate patterns with an exclamation (!).
+# For example, you can ignore all files in a docs folder with the file extension .md:
+#docs/*.md
+# Then explicitly reverse the ignore rule for a single file:
+#!docs/README.md
diff --git a/samples/server/others/kotlin-server/polymorphism/.openapi-generator/FILES b/samples/server/others/kotlin-server/polymorphism/.openapi-generator/FILES
new file mode 100644
index 000000000000..339ec9249554
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism/.openapi-generator/FILES
@@ -0,0 +1,8 @@
+README.md
+build.gradle.kts
+gradle.properties
+settings.gradle
+src/main/kotlin/org/openapitools/server/Main.kt
+src/main/kotlin/org/openapitools/server/models/Cat.kt
+src/main/kotlin/org/openapitools/server/models/Dog.kt
+src/main/kotlin/org/openapitools/server/models/Pet.kt
diff --git a/samples/server/others/kotlin-server/polymorphism/.openapi-generator/VERSION b/samples/server/others/kotlin-server/polymorphism/.openapi-generator/VERSION
new file mode 100644
index 000000000000..909dcd0eca63
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism/.openapi-generator/VERSION
@@ -0,0 +1 @@
+7.19.0-SNAPSHOT
diff --git a/samples/server/others/kotlin-server/polymorphism/README.md b/samples/server/others/kotlin-server/polymorphism/README.md
new file mode 100644
index 000000000000..23ecad1084f8
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism/README.md
@@ -0,0 +1,61 @@
+# org.openapitools.server - Kotlin Server library for Basic polymorphism example without discriminator
+
+No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
+
+Generated by OpenAPI Generator 7.19.0-SNAPSHOT.
+
+## Build
+
+First, create the gradle wrapper script:
+
+```
+gradle wrapper
+```
+
+Then, run:
+
+```
+./gradlew check assemble
+```
+
+This runs all tests and packages the library.
+
+## Running
+
+The server builds as a fat jar with a main entrypoint. To start the service, run `java -jar ./build/libs/kotlin-server-polymorphism.jar`.
+
+You may also run in docker:
+
+```
+docker build -t kotlin-server-polymorphism .
+docker run -p 8080:8080 kotlin-server-polymorphism
+```
+
+## Features/Implementation Notes
+
+* Supports JSON inputs/outputs, File inputs, and Form inputs (see ktor documentation for more info).
+* ~Supports collection formats for query parameters: csv, tsv, ssv, pipes.~
+* Some Kotlin and Java types are fully qualified to avoid conflicts with types defined in OpenAPI definitions.
+
+
+## Documentation for API Endpoints
+
+All URIs are relative to *http://localhost*
+
+Class | Method | HTTP request | Description
+------------ | ------------- | ------------- | -------------
+
+
+
+## Documentation for Models
+
+ - [org.openapitools.server.models.Cat](docs/Cat.md)
+ - [org.openapitools.server.models.Dog](docs/Dog.md)
+ - [org.openapitools.server.models.Pet](docs/Pet.md)
+
+
+
+## Documentation for Authorization
+
+Endpoints do not require authorization.
+
diff --git a/samples/server/others/kotlin-server/polymorphism/build.gradle.kts b/samples/server/others/kotlin-server/polymorphism/build.gradle.kts
new file mode 100644
index 000000000000..220ec0c53ac7
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism/build.gradle.kts
@@ -0,0 +1,33 @@
+plugins {
+ kotlin("jvm") version "2.0.21"
+}
+
+group = "org.openapitools"
+version = "1.0.0"
+
+kotlin {
+ jvmToolchain(21)
+}
+
+java {
+ toolchain {
+ languageVersion.set(JavaLanguageVersion.of(21))
+ }
+}
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ implementation("io.javalin:javalin:6.1.6")
+ implementation("com.fasterxml.jackson.core:jackson-databind:2.17.1")
+ implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.17.1")
+ implementation("org.slf4j:slf4j-simple:2.0.13")
+
+ testImplementation("org.jetbrains.kotlin:kotlin-test")
+}
+
+tasks.test {
+ useJUnitPlatform()
+}
diff --git a/samples/server/others/kotlin-server/polymorphism/gradle.properties b/samples/server/others/kotlin-server/polymorphism/gradle.properties
new file mode 100644
index 000000000000..5f1ed7bbe024
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism/gradle.properties
@@ -0,0 +1 @@
+org.gradle.caching=true
\ No newline at end of file
diff --git a/samples/server/others/kotlin-server/polymorphism/settings.gradle b/samples/server/others/kotlin-server/polymorphism/settings.gradle
new file mode 100644
index 000000000000..006505e368da
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism/settings.gradle
@@ -0,0 +1 @@
+rootProject.name = 'kotlin-server-polymorphism'
\ No newline at end of file
diff --git a/samples/server/others/kotlin-server/polymorphism/src/main/kotlin/org/openapitools/server/Main.kt b/samples/server/others/kotlin-server/polymorphism/src/main/kotlin/org/openapitools/server/Main.kt
new file mode 100644
index 000000000000..dba7f137ec60
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism/src/main/kotlin/org/openapitools/server/Main.kt
@@ -0,0 +1,16 @@
+package org.openapitools.server
+
+import io.javalin.Javalin
+import io.javalin.apibuilder.ApiBuilder.*
+
+
+fun main() {
+
+ val app = Javalin
+ .create { config ->
+ config.router.apiBuilder {
+ }
+ }
+
+ app.start()
+}
diff --git a/samples/server/others/kotlin-server/polymorphism/src/main/kotlin/org/openapitools/server/models/Cat.kt b/samples/server/others/kotlin-server/polymorphism/src/main/kotlin/org/openapitools/server/models/Cat.kt
new file mode 100644
index 000000000000..9daf3b5219e7
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism/src/main/kotlin/org/openapitools/server/models/Cat.kt
@@ -0,0 +1,41 @@
+/**
+ * Basic polymorphism example without discriminator
+ * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
+ *
+ * The version of the OpenAPI document: 1.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+*/
+package org.openapitools.server.models
+
+
+/**
+ * A pet cat
+ * @param huntingSkill The measured skill for hunting
+ * @param petType
+ */
+data class Cat(
+ /* The measured skill for hunting */
+
+ @field:com.fasterxml.jackson.annotation.JsonProperty("huntingSkill")
+ val huntingSkill: Cat.HuntingSkill,
+
+ @field:com.fasterxml.jackson.annotation.JsonProperty("petType")
+ val petType: kotlin.Any? = null
+)
+{
+ /**
+ * The measured skill for hunting
+ * Values: clueless,lazy,adventurous,aggressive
+ */
+ enum class HuntingSkill(val value: kotlin.String){
+ clueless("clueless"),
+ lazy("lazy"),
+ adventurous("adventurous"),
+ aggressive("aggressive");
+ }
+}
+
diff --git a/samples/server/others/kotlin-server/polymorphism/src/main/kotlin/org/openapitools/server/models/Dog.kt b/samples/server/others/kotlin-server/polymorphism/src/main/kotlin/org/openapitools/server/models/Dog.kt
new file mode 100644
index 000000000000..803468f25c14
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism/src/main/kotlin/org/openapitools/server/models/Dog.kt
@@ -0,0 +1,29 @@
+/**
+ * Basic polymorphism example without discriminator
+ * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
+ *
+ * The version of the OpenAPI document: 1.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+*/
+package org.openapitools.server.models
+
+
+/**
+ * A pet dog
+ * @param packSize the size of the pack the dog is from
+ * @param petType
+ */
+data class Dog(
+ /* the size of the pack the dog is from */
+
+ @field:com.fasterxml.jackson.annotation.JsonProperty("packSize")
+ val packSize: kotlin.Int = 0,
+
+ @field:com.fasterxml.jackson.annotation.JsonProperty("petType")
+ val petType: kotlin.Any? = null
+)
+
diff --git a/samples/server/others/kotlin-server/polymorphism/src/main/kotlin/org/openapitools/server/models/Pet.kt b/samples/server/others/kotlin-server/polymorphism/src/main/kotlin/org/openapitools/server/models/Pet.kt
new file mode 100644
index 000000000000..438e3b01ae8d
--- /dev/null
+++ b/samples/server/others/kotlin-server/polymorphism/src/main/kotlin/org/openapitools/server/models/Pet.kt
@@ -0,0 +1,52 @@
+/**
+ * Basic polymorphism example without discriminator
+ * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
+ *
+ * The version of the OpenAPI document: 1.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+*/
+package org.openapitools.server.models
+
+import org.openapitools.server.models.Cat
+import org.openapitools.server.models.Dog
+
+/**
+ *
+ * @param name
+ * @param petType
+ * @param huntingSkill The measured skill for hunting
+ * @param packSize the size of the pack the dog is from
+ */
+data class Pet(
+
+ @field:com.fasterxml.jackson.annotation.JsonProperty("name")
+ val name: kotlin.String,
+
+ @field:com.fasterxml.jackson.annotation.JsonProperty("petType")
+ val petType: kotlin.Any?,
+ /* The measured skill for hunting */
+
+ @field:com.fasterxml.jackson.annotation.JsonProperty("huntingSkill")
+ val huntingSkill: Pet.HuntingSkill,
+ /* the size of the pack the dog is from */
+
+ @field:com.fasterxml.jackson.annotation.JsonProperty("packSize")
+ val packSize: kotlin.Int = 0
+)
+{
+ /**
+ * The measured skill for hunting
+ * Values: clueless,lazy,adventurous,aggressive
+ */
+ enum class HuntingSkill(val value: kotlin.String){
+ clueless("clueless"),
+ lazy("lazy"),
+ adventurous("adventurous"),
+ aggressive("aggressive");
+ }
+}
+