Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import com.samskivert.mustache.Mustache;
import com.samskivert.mustache.Mustache.Lambda;
import com.samskivert.mustache.Template;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import lombok.Getter;
Expand Down Expand Up @@ -425,6 +424,7 @@ public void processOpts() {
importMapping.put("JsonProperty", "com.fasterxml.jackson.annotation.JsonProperty");
importMapping.put("JsonSubTypes", "com.fasterxml.jackson.annotation.JsonSubTypes");
importMapping.put("JsonTypeInfo", "com.fasterxml.jackson.annotation.JsonTypeInfo");
importMapping.put("JsonIgnoreProperties", "com.fasterxml.jackson.annotation.JsonIgnoreProperties");
// import JsonCreator if JsonProperty is imported
// used later in recursive import in postProcessingModels
importMapping.put("com.fasterxml.jackson.annotation.JsonProperty", "com.fasterxml.jackson.annotation.JsonCreator");
Expand Down Expand Up @@ -827,7 +827,7 @@ public void postProcessModelProperty(CodegenModel model, CodegenProperty propert
}

if (model.discriminator != null && additionalProperties.containsKey("jackson")) {
model.imports.addAll(Arrays.asList("JsonSubTypes", "JsonTypeInfo"));
model.imports.addAll(Arrays.asList("JsonSubTypes", "JsonTypeInfo", "JsonIgnoreProperties"));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import com.fasterxml.jackson.annotation.JsonEnumDefaultValue
{{/enumUnknownDefaultCase}}
import com.fasterxml.jackson.annotation.JsonProperty
{{#discriminator}}
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
import com.fasterxml.jackson.annotation.JsonSubTypes
import com.fasterxml.jackson.annotation.JsonTypeInfo
{{/discriminator}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
@JsonIgnoreProperties(
value = ["{{{discriminator.propertyBaseName}}}"], // ignore manually set {{{discriminator.propertyBaseName}}}, it will be automatically generated by Jackson during serialization
allowSetters = true // allows the {{{discriminator.propertyBaseName}}} to be set during deserialization
)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "{{{discriminator.propertyBaseName}}}", visible = true)
@JsonSubTypes(
{{#discriminator.mappedModels}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
{{#jackson}}

@JsonIgnoreProperties(
value = ["{{{discriminator.propertyBaseName}}}"], // ignore manually set {{{discriminator.propertyBaseName}}}, it will be automatically generated by Jackson during serialization
allowSetters = true // allows the {{{discriminator.propertyBaseName}}} to be set during deserialization
)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "{{{discriminator.propertyBaseName}}}", visible = true)
@JsonSubTypes(
{{#discriminator.mappedModels}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,15 @@

import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.media.*;
import lombok.Getter;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import org.openapitools.codegen.*;
import org.openapitools.codegen.antlr4.KotlinLexer;
import org.openapitools.codegen.antlr4.KotlinParser;
import org.openapitools.codegen.antlr4.KotlinParserBaseListener;
import org.openapitools.codegen.config.CodegenConfigurator;
import org.openapitools.codegen.languages.KotlinClientCodegen;
import org.openapitools.codegen.languages.KotlinServerCodegen;
import org.openapitools.codegen.testutils.ConfigAssert;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
Expand All @@ -45,8 +43,6 @@
import java.util.Map;

import static org.openapitools.codegen.CodegenConstants.*;
import static org.openapitools.codegen.languages.KotlinServerCodegen.Constants.INTERFACE_ONLY;
import static org.openapitools.codegen.languages.KotlinServerCodegen.Constants.RETURN_RESPONSE;

@SuppressWarnings("static-method")
public class KotlinClientCodegenModelTest {
Expand Down Expand Up @@ -534,7 +530,7 @@ private void givenSchemaObjectPropertyNameContainsDollarSignWhenGenerateThenDoll
}

@Test(description = "generate polymorphic kotlinx_serialization model")
public void polymorphicKotlinxSerialzation() throws IOException {
public void polymorphicKotlinxSerialization() throws IOException {
File output = Files.createTempDirectory("test").toFile();
output.deleteOnExit();

Expand Down Expand Up @@ -573,6 +569,54 @@ public void polymorphicKotlinxSerialzation() throws IOException {
TestUtils.assertFileContains(birdKt, "@SerialName(value = \"BIRD\")");
}

@Test(description = "generate polymorphic jackson model")
public void polymorphicJacksonSerialization() throws IOException {
File output = Files.createTempDirectory("test").toFile();
// output.deleteOnExit();

final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName("kotlin")
.setLibrary("jvm-okhttp4")
.setAdditionalProperties(new HashMap<>() {{
put(CodegenConstants.SERIALIZATION_LIBRARY, "jackson");
put(CodegenConstants.MODEL_PACKAGE, "xyz.abcdef.model");
}})
.setInputSpec("src/test/resources/3_0/kotlin/polymorphism.yaml")
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));

final ClientOptInput clientOptInput = configurator.toClientOptInput();
DefaultGenerator generator = new DefaultGenerator();
List<File> files = generator.opts(clientOptInput).generate();

Assert.assertEquals(files.size(), 28);

final Path animalKt = Paths.get(output + "/src/main/kotlin/xyz/abcdef/model/Animal.kt");
// base has extra jackson imports
TestUtils.assertFileContains(animalKt, "import com.fasterxml.jackson.annotation.JsonIgnoreProperties");
TestUtils.assertFileContains(animalKt, "import com.fasterxml.jackson.annotation.JsonSubTypes");
TestUtils.assertFileContains(animalKt, "import com.fasterxml.jackson.annotation.JsonTypeInfo");
// and these are being used
TestUtils.assertFileContains(animalKt, "@JsonIgnoreProperties");
TestUtils.assertFileContains(animalKt, "@JsonSubTypes");
TestUtils.assertFileContains(animalKt, "@JsonTypeInfo");
// base is interface
TestUtils.assertFileContains(animalKt, "interface Animal");
// base properties are present
TestUtils.assertFileContains(animalKt, "val id");
TestUtils.assertFileContains(animalKt, "val optionalProperty");
// base doesn't contain discriminator
TestUtils.assertFileNotContains(animalKt, "val discriminator");

final Path birdKt = Paths.get(output + "/src/main/kotlin/xyz/abcdef/model/Bird.kt");
// derived has serial name set to mapping key
TestUtils.assertFileContains(birdKt, "data class Bird");
// derived properties are overridden
TestUtils.assertFileContains(birdKt, "override val id");
TestUtils.assertFileContains(birdKt, "override val optionalProperty");
// derived doesn't contain disciminator
TestUtils.assertFileNotContains(birdKt, "val discriminator");
}

private static class ModelNameTest {
private final String expectedName;
private final String expectedClassName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,45 @@ public void gradleWrapperIsGenerated() throws IOException {
//Different because file is not a text file
assertTrue(Files.exists(gradleWrapperJarCloud));
}

@Test(description = "generate polymorphic jackson model")
public void polymorphicJacksonSerialization() throws IOException {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
output.deleteOnExit();

KotlinSpringServerCodegen codegen = new KotlinSpringServerCodegen() ;
codegen.setOutputDir(output.getAbsolutePath());

new DefaultGenerator().opts(
new ClientOptInput()
.openAPI(TestUtils.parseSpec("src/test/resources/3_0/kotlin/polymorphism.yaml"))
.config(codegen)
).generate();

final Path animalKt = Paths.get(output + "/src/main/kotlin/org/openapitools/model/Animal.kt");
// base has extra jackson imports
TestUtils.assertFileContains(animalKt, "import com.fasterxml.jackson.annotation.JsonIgnoreProperties");
TestUtils.assertFileContains(animalKt, "import com.fasterxml.jackson.annotation.JsonSubTypes");
TestUtils.assertFileContains(animalKt, "import com.fasterxml.jackson.annotation.JsonTypeInfo");
// and these are being used
TestUtils.assertFileContains(animalKt, "@JsonIgnoreProperties");
TestUtils.assertFileContains(animalKt, "@JsonSubTypes");
TestUtils.assertFileContains(animalKt, "@JsonTypeInfo");
// base is interface
TestUtils.assertFileContains(animalKt, "interface Animal");
// base properties are present
TestUtils.assertFileContains(animalKt, "val id");
TestUtils.assertFileContains(animalKt, "val optionalProperty");
// base doesn't contain discriminator
TestUtils.assertFileNotContains(animalKt, "val discriminator");

final Path birdKt = Paths.get(output + "/src/main/kotlin/org/openapitools/model/Bird.kt");
// derived has serial name set to mapping key
TestUtils.assertFileContains(birdKt, "data class Bird");
// derived properties are overridden
TestUtils.assertFileContains(birdKt, "override val id");
TestUtils.assertFileContains(birdKt, "override val optionalProperty");
// derived doesn't contain disciminator
TestUtils.assertFileNotContains(birdKt, "val discriminator");
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.openapitools.model

import java.util.Objects
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.annotation.JsonSubTypes
import com.fasterxml.jackson.annotation.JsonTypeInfo
Expand All @@ -20,7 +21,10 @@ import io.swagger.v3.oas.annotations.media.Schema
* @param className
* @param color
*/

@JsonIgnoreProperties(
value = ["className"], // ignore manually set className, it will be automatically generated by Jackson during serialization
allowSetters = true // allows the className to be set during deserialization
)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "className", visible = true)
@JsonSubTypes(
JsonSubTypes.Type(value = Cat::class, name = "CAT"),
Expand Down
Loading