Skip to content

Commit

Permalink
clone Schema using AnnotationUtils.clone with WA (to clone schemas wi…
Browse files Browse the repository at this point in the history
…th example field set)
  • Loading branch information
dreambrother committed Jun 5, 2024
1 parent 0621d34 commit eb0b0b7
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2862,7 +2862,9 @@ private void mergeProperties(Map<String, Schema> existingProperties, Map<String,
if (null != existingProperties && null != newProperties) {
Schema existingType = existingProperties.get("type");
Schema newType = newProperties.get("type");
newProperties.forEach((key, value) -> existingProperties.put(key, ModelUtils.cloneSchema(value)));
newProperties.forEach((key, value) ->
existingProperties.put(key, ModelUtils.cloneSchema(value, specVersionGreaterThanOrEqualTo310(openAPI)))
);
if (null != existingType && null != newType && null != newType.getEnum() && !newType.getEnum().isEmpty()) {
for (Object e : newType.getEnum()) {
// ensure all interface enum types are added to schema
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@

package org.openapitools.codegen.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator;
import io.swagger.v3.core.util.AnnotationsUtils;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.PathItem;
Expand Down Expand Up @@ -54,7 +53,6 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;

import static org.openapitools.codegen.utils.OnceLogger.once;
Expand All @@ -64,6 +62,8 @@ public class ModelUtils {

private static final String URI_FORMAT = "uri";

private static final Set<String> OPENAPI_TYPES = Set.of("array", "integer", "number", "boolean", "string", "object");

private static final String generateAliasAsModelKey = "generateAliasAsModel";

// A vendor extension to track the value of the 'swagger' field in a 2.0 doc, if applicable.
Expand All @@ -76,16 +76,10 @@ public class ModelUtils {

private static final ObjectMapper JSON_MAPPER;
private static final ObjectMapper YAML_MAPPER;
private static final ObjectMapper TYPED_JSON_MAPPER = new ObjectMapper();

static {
JSON_MAPPER = ObjectMapperFactory.createJson();
YAML_MAPPER = ObjectMapperFactory.createYaml();

BasicPolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder()
.allowIfSubType(Object.class)
.build();
TYPED_JSON_MAPPER.activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.EVERYTHING);
}

public static boolean isDisallowAdditionalPropertiesIfNotPresent() {
Expand Down Expand Up @@ -2186,13 +2180,19 @@ public static boolean isParent(Schema schema) {
return false;
}

public static Schema cloneSchema(Schema schema) {
try {
String json = TYPED_JSON_MAPPER.writeValueAsString(schema);
return TYPED_JSON_MAPPER.readValue(json, schema.getClass());
} catch (JsonProcessingException ex) {
LOGGER.error("Can't clone schema {}", schema, ex);
return schema;
public static Schema cloneSchema(Schema schema, boolean openapi31) {
if (openapi31) {
return AnnotationsUtils.clone(schema, openapi31);
} else {
// AnnotationsUtils.clone doesn't support custom schema types for OpenAPI < 3.1
String schemaType = schema.getType();
if (schemaType != null && !OPENAPI_TYPES.contains(schemaType)) {
schema.setType(null);
}
Schema result = AnnotationsUtils.clone(schema, openapi31);
schema.setType(schemaType);
result.setType(schemaType);
return result;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -399,51 +399,66 @@ public void testCloneNumberSchema() {
.name("test-schema")
.minimum(new BigDecimal(100));

Schema deepCopy = ModelUtils.cloneSchema(schema);
Schema deepCopy = ModelUtils.cloneSchema(schema, false);

Assert.assertEquals(schema, deepCopy);
Assert.assertEquals(deepCopy, schema);
Assert.assertNotSame(deepCopy, schema);
}

@Test
public void testCloneCustomSchema() {
Schema schema = new Schema().type("money");
Schema schema = new ObjectSchema().type("money");

Schema deepCopy = ModelUtils.cloneSchema(schema);
Schema deepCopy = ModelUtils.cloneSchema(schema, false);

Assert.assertEquals(schema, deepCopy);
Assert.assertEquals(deepCopy, schema);
Assert.assertNotSame(deepCopy, schema);
}

@Test
public void testCloneComposedSchema() {
Schema base1 = new Schema()
Schema base1 = new ObjectSchema()
.name("Base1")
.addProperty("foo", new StringSchema());
Schema base2 = new Schema()
Schema base2 = new ObjectSchema()
.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);
Schema deepCopy = ModelUtils.cloneSchema(composedSchema, false);

Assert.assertEquals(composedSchema, deepCopy);
Assert.assertEquals(deepCopy, composedSchema);
Assert.assertNotSame(deepCopy, composedSchema);
}

@Test
public void testCloneArrayOfEnumsSchema() {
Schema arraySchema = new Schema()
Schema schema = new ArraySchema()
.name("ArrayType")
.type("array")
.items(new Schema()
.items(new StringSchema()
.type("string")
._enum(List.of("SUCCESS", "FAILURE", "SKIPPED"))
)
._default(List.of("SUCCESS", "FAILURE"));

var deepCopy = ModelUtils.cloneSchema(arraySchema);
Schema deepCopy = ModelUtils.cloneSchema(schema, false);

Assert.assertEquals(arraySchema, deepCopy);
Assert.assertEquals(deepCopy, schema);
Assert.assertNotSame(deepCopy, schema);
}

@Test
public void testCloneDateTimeSchemaWithExample() {
Schema schema = new DateTimeSchema()
.example("2020-02-02T20:20:20.000222Z");

Schema deepCopy = ModelUtils.cloneSchema(schema, false);

Assert.assertEquals(deepCopy, schema);
Assert.assertNotSame(deepCopy, schema);
}
}

0 comments on commit eb0b0b7

Please sign in to comment.