forked from loafle/openapi-generator-original
Properties with custom types inheritance fix (#18052)
* custom types support in inheritance fix * files changed after scripts run * remove unused method * move cloneSchema to ModelUtils * imports * changes after scripts run * test cloning array of enums schema
This commit is contained in:
@@ -397,6 +397,11 @@
|
|||||||
<artifactId>jackson-datatype-joda</artifactId>
|
<artifactId>jackson-datatype-joda</artifactId>
|
||||||
<version>${jackson.version}</version>
|
<version>${jackson.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-annotations</artifactId>
|
||||||
|
<version>${jackson.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.joschi.jackson</groupId>
|
<groupId>com.github.joschi.jackson</groupId>
|
||||||
<artifactId>jackson-datatype-threetenbp</artifactId>
|
<artifactId>jackson-datatype-threetenbp</artifactId>
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
package org.openapitools.codegen;
|
package org.openapitools.codegen;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
|
||||||
import com.github.benmanes.caffeine.cache.Cache;
|
import com.github.benmanes.caffeine.cache.Cache;
|
||||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||||
import com.github.benmanes.caffeine.cache.Ticker;
|
import com.github.benmanes.caffeine.cache.Ticker;
|
||||||
@@ -26,7 +25,6 @@ import com.google.common.collect.ImmutableMap;
|
|||||||
import com.samskivert.mustache.Mustache;
|
import com.samskivert.mustache.Mustache;
|
||||||
import com.samskivert.mustache.Mustache.Compiler;
|
import com.samskivert.mustache.Mustache.Compiler;
|
||||||
import com.samskivert.mustache.Mustache.Lambda;
|
import com.samskivert.mustache.Mustache.Lambda;
|
||||||
import io.swagger.v3.core.util.AnnotationsUtils;
|
|
||||||
import io.swagger.v3.core.util.Json;
|
import io.swagger.v3.core.util.Json;
|
||||||
import io.swagger.v3.oas.models.OpenAPI;
|
import io.swagger.v3.oas.models.OpenAPI;
|
||||||
import io.swagger.v3.oas.models.Operation;
|
import io.swagger.v3.oas.models.Operation;
|
||||||
@@ -65,7 +63,6 @@ import org.openapitools.codegen.model.WebhooksMap;
|
|||||||
import org.openapitools.codegen.serializer.SerializerUtils;
|
import org.openapitools.codegen.serializer.SerializerUtils;
|
||||||
import org.openapitools.codegen.templating.MustacheEngineAdapter;
|
import org.openapitools.codegen.templating.MustacheEngineAdapter;
|
||||||
import org.openapitools.codegen.templating.mustache.*;
|
import org.openapitools.codegen.templating.mustache.*;
|
||||||
import org.openapitools.codegen.utils.CamelizeOption;
|
|
||||||
import org.openapitools.codegen.utils.ModelUtils;
|
import org.openapitools.codegen.utils.ModelUtils;
|
||||||
import org.openapitools.codegen.utils.OneOfImplementorAdditionalData;
|
import org.openapitools.codegen.utils.OneOfImplementorAdditionalData;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -2945,11 +2942,7 @@ public class DefaultCodegen implements CodegenConfig {
|
|||||||
if (null != existingProperties && null != newProperties) {
|
if (null != existingProperties && null != newProperties) {
|
||||||
Schema existingType = existingProperties.get("type");
|
Schema existingType = existingProperties.get("type");
|
||||||
Schema newType = newProperties.get("type");
|
Schema newType = newProperties.get("type");
|
||||||
newProperties.forEach((key, value) ->
|
newProperties.forEach((key, value) -> existingProperties.put(key, ModelUtils.cloneSchema(value)));
|
||||||
existingProperties.put(
|
|
||||||
key,
|
|
||||||
ModelUtils.cloneSchema(value, specVersionGreaterThanOrEqualTo310(openAPI))
|
|
||||||
));
|
|
||||||
if (null != existingType && null != newType && null != newType.getEnum() && !newType.getEnum().isEmpty()) {
|
if (null != existingType && null != newType && null != newType.getEnum() && !newType.getEnum().isEmpty()) {
|
||||||
for (Object e : newType.getEnum()) {
|
for (Object e : newType.getEnum()) {
|
||||||
// ensure all interface enum types are added to schema
|
// ensure all interface enum types are added to schema
|
||||||
|
|||||||
@@ -17,9 +17,10 @@
|
|||||||
|
|
||||||
package org.openapitools.codegen.utils;
|
package org.openapitools.codegen.utils;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import io.swagger.v3.core.util.AnnotationsUtils;
|
import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator;
|
||||||
import io.swagger.v3.oas.models.OpenAPI;
|
import io.swagger.v3.oas.models.OpenAPI;
|
||||||
import io.swagger.v3.oas.models.Operation;
|
import io.swagger.v3.oas.models.Operation;
|
||||||
import io.swagger.v3.oas.models.PathItem;
|
import io.swagger.v3.oas.models.PathItem;
|
||||||
@@ -75,10 +76,16 @@ public class ModelUtils {
|
|||||||
|
|
||||||
private static final ObjectMapper JSON_MAPPER;
|
private static final ObjectMapper JSON_MAPPER;
|
||||||
private static final ObjectMapper YAML_MAPPER;
|
private static final ObjectMapper YAML_MAPPER;
|
||||||
|
private static final ObjectMapper TYPED_JSON_MAPPER = new ObjectMapper();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
JSON_MAPPER = ObjectMapperFactory.createJson();
|
JSON_MAPPER = ObjectMapperFactory.createJson();
|
||||||
YAML_MAPPER = ObjectMapperFactory.createYaml();
|
YAML_MAPPER = ObjectMapperFactory.createYaml();
|
||||||
|
|
||||||
|
BasicPolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder()
|
||||||
|
.allowIfSubType(Object.class)
|
||||||
|
.build();
|
||||||
|
TYPED_JSON_MAPPER.activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.EVERYTHING);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isDisallowAdditionalPropertiesIfNotPresent() {
|
public static boolean isDisallowAdditionalPropertiesIfNotPresent() {
|
||||||
@@ -2179,24 +2186,14 @@ public class ModelUtils {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static Schema cloneSchema(Schema schema) {
|
||||||
* Returns a clone of the schema.
|
try {
|
||||||
*
|
String json = TYPED_JSON_MAPPER.writeValueAsString(schema);
|
||||||
* @param schema the schema.
|
return TYPED_JSON_MAPPER.readValue(json, schema.getClass());
|
||||||
* @param specVersionGreaterThanOrEqualTo310 true if spec version is 3.1.0 or later.
|
} catch (JsonProcessingException ex) {
|
||||||
* @return a clone of the schema.
|
LOGGER.error("Can't clone schema {}", schema, ex);
|
||||||
*/
|
return schema;
|
||||||
public static Schema cloneSchema(Schema schema, boolean specVersionGreaterThanOrEqualTo310) {
|
|
||||||
Schema clone = AnnotationsUtils.clone(schema, specVersionGreaterThanOrEqualTo310);
|
|
||||||
|
|
||||||
// check to see if type is set and clone it if needed
|
|
||||||
// in openapi-generator, we also store type in `type` for 3.1 schema
|
|
||||||
// to make it backward compatible with the rest of the code base.
|
|
||||||
if (schema.getType() != null) {
|
|
||||||
clone.setType(schema.getType());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return clone;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import org.testng.annotations.Test;
|
|||||||
|
|
||||||
public class JavaInheritanceTest {
|
public class JavaInheritanceTest {
|
||||||
|
|
||||||
|
|
||||||
@Test(description = "convert a composed model with parent")
|
@Test(description = "convert a composed model with parent")
|
||||||
public void javaInheritanceTest() {
|
public void javaInheritanceTest() {
|
||||||
final Schema parentModel = new Schema().name("Base");
|
final Schema parentModel = new Schema().name("Base");
|
||||||
@@ -181,4 +180,32 @@ public class JavaInheritanceTest {
|
|||||||
Assert.assertFalse(propertyCD.required);
|
Assert.assertFalse(propertyCD.required);
|
||||||
Assert.assertEquals(cm.requiredVars.size() + cm.optionalVars.size(), cm.allVars.size());
|
Assert.assertEquals(cm.requiredVars.size() + cm.optionalVars.size(), cm.allVars.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(description = "convert a composed model with parent with custom schema param")
|
||||||
|
public void javaInheritanceWithCustomSchemaTest() {
|
||||||
|
Schema custom = new Schema()
|
||||||
|
.name("Custom")
|
||||||
|
.addProperty("value", new StringSchema());
|
||||||
|
Schema parentModel = new Schema()
|
||||||
|
.name("Base")
|
||||||
|
.addProperty("customProperty", new Schema().type("custom"));
|
||||||
|
Schema schema = new ComposedSchema()
|
||||||
|
.name("Composed")
|
||||||
|
.addAllOfItem(new Schema().$ref("Base"));
|
||||||
|
|
||||||
|
OpenAPI openAPI = TestUtils.createOpenAPI();
|
||||||
|
openAPI.setComponents(new Components()
|
||||||
|
.addSchemas(custom.getName(), custom)
|
||||||
|
.addSchemas(parentModel.getName(), parentModel)
|
||||||
|
.addSchemas(schema.getName(), schema)
|
||||||
|
);
|
||||||
|
|
||||||
|
JavaClientCodegen codegen = new JavaClientCodegen();
|
||||||
|
codegen.setOpenAPI(openAPI);
|
||||||
|
codegen.schemaMapping()
|
||||||
|
.put("custom", custom.getName());
|
||||||
|
CodegenModel model = codegen.fromModel("sample", schema);
|
||||||
|
|
||||||
|
Assert.assertTrue(model.imports.contains(custom.getName()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import org.openapitools.codegen.TestUtils;
|
|||||||
import org.testng.Assert;
|
import org.testng.Assert;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class ModelUtilsTest {
|
public class ModelUtilsTest {
|
||||||
@@ -391,4 +392,58 @@ public class ModelUtilsTest {
|
|||||||
Schema complexComposedSchema = ModelUtils.getSchema(openAPI, "ComplexComposedSchema");
|
Schema complexComposedSchema = ModelUtils.getSchema(openAPI, "ComplexComposedSchema");
|
||||||
Assert.assertTrue(ModelUtils.isComplexComposedSchema(complexComposedSchema));
|
Assert.assertTrue(ModelUtils.isComplexComposedSchema(complexComposedSchema));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCloneNumberSchema() {
|
||||||
|
Schema schema = new NumberSchema()
|
||||||
|
.name("test-schema")
|
||||||
|
.minimum(new BigDecimal(100));
|
||||||
|
|
||||||
|
Schema deepCopy = ModelUtils.cloneSchema(schema);
|
||||||
|
|
||||||
|
Assert.assertEquals(schema, deepCopy);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCloneCustomSchema() {
|
||||||
|
Schema schema = new Schema().type("money");
|
||||||
|
|
||||||
|
Schema deepCopy = ModelUtils.cloneSchema(schema);
|
||||||
|
|
||||||
|
Assert.assertEquals(schema, deepCopy);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCloneComposedSchema() {
|
||||||
|
Schema base1 = new Schema()
|
||||||
|
.name("Base1")
|
||||||
|
.addProperty("foo", new StringSchema());
|
||||||
|
Schema base2 = new Schema()
|
||||||
|
.name("Base2")
|
||||||
|
.addProperty("bar", new StringSchema());
|
||||||
|
Schema composedSchema = new ComposedSchema()
|
||||||
|
.name("Composed")
|
||||||
|
.allOf(List.of(base1, base2))
|
||||||
|
.addProperty("baz", new StringSchema());
|
||||||
|
|
||||||
|
var deepCopy = ModelUtils.cloneSchema(composedSchema);
|
||||||
|
|
||||||
|
Assert.assertEquals(composedSchema, deepCopy);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCloneArrayOfEnumsSchema() {
|
||||||
|
Schema arraySchema = new Schema()
|
||||||
|
.name("ArrayType")
|
||||||
|
.type("array")
|
||||||
|
.items(new Schema()
|
||||||
|
.type("string")
|
||||||
|
._enum(List.of("SUCCESS", "FAILURE", "SKIPPED"))
|
||||||
|
)
|
||||||
|
._default(List.of("SUCCESS", "FAILURE"));
|
||||||
|
|
||||||
|
var deepCopy = ModelUtils.cloneSchema(arraySchema);
|
||||||
|
|
||||||
|
Assert.assertEquals(arraySchema, deepCopy);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,13 +30,13 @@ DataQuery <- R6::R6Class(
|
|||||||
#' Initialize a new DataQuery class.
|
#' Initialize a new DataQuery class.
|
||||||
#'
|
#'
|
||||||
#' @param id Query
|
#' @param id Query
|
||||||
#' @param outcomes outcomes. Default to [SUCCESS, FAILURE].
|
#' @param outcomes outcomes. Default to ["SUCCESS","FAILURE"].
|
||||||
#' @param suffix test suffix
|
#' @param suffix test suffix
|
||||||
#' @param text Some text containing white spaces
|
#' @param text Some text containing white spaces
|
||||||
#' @param date A date
|
#' @param date A date
|
||||||
#' @param ... Other optional arguments.
|
#' @param ... Other optional arguments.
|
||||||
#' @export
|
#' @export
|
||||||
initialize = function(`id` = NULL, `outcomes` = [SUCCESS, FAILURE], `suffix` = NULL, `text` = NULL, `date` = NULL, ...) {
|
initialize = function(`id` = NULL, `outcomes` = ["SUCCESS","FAILURE"], `suffix` = NULL, `text` = NULL, `date` = NULL, ...) {
|
||||||
if (!is.null(`id`)) {
|
if (!is.null(`id`)) {
|
||||||
if (!(is.numeric(`id`) && length(`id`) == 1)) {
|
if (!(is.numeric(`id`) && length(`id`) == 1)) {
|
||||||
stop(paste("Error! Invalid data for `id`. Must be an integer:", `id`))
|
stop(paste("Error! Invalid data for `id`. Must be an integer:", `id`))
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
Name | Type | Description | Notes
|
Name | Type | Description | Notes
|
||||||
------------ | ------------- | ------------- | -------------
|
------------ | ------------- | ------------- | -------------
|
||||||
**id** | **integer** | Query | [optional]
|
**id** | **integer** | Query | [optional]
|
||||||
**outcomes** | **array[character]** | | [optional] [default to [SUCCESS, FAILURE]] [Enum: ]
|
**outcomes** | **array[character]** | | [optional] [default to ["SUCCESS","FAILURE"]] [Enum: ]
|
||||||
**suffix** | **character** | test suffix | [optional]
|
**suffix** | **character** | test suffix | [optional]
|
||||||
**text** | **character** | Some text containing white spaces | [optional]
|
**text** | **character** | Some text containing white spaces | [optional]
|
||||||
**date** | **character** | A date | [optional]
|
**date** | **character** | A date | [optional]
|
||||||
|
|||||||
Reference in New Issue
Block a user