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 @@ -33,12 +33,11 @@
import org.slf4j.LoggerFactory;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static org.openapitools.codegen.utils.ModelUtils.simplyOneOfAnyOfWithOnlyOneNonNullSubSchema;
import static org.openapitools.codegen.utils.ModelUtils.simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema;
import static org.openapitools.codegen.utils.StringUtils.getUniqueString;

public class OpenAPINormalizer {
Expand Down Expand Up @@ -1318,7 +1317,7 @@ protected Schema processSimplifyOneOf(Schema schema) {
}
}

schema = simplyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, schema, oneOfSchemas);
schema = simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, schema, oneOfSchemas);

if (ModelUtils.isIntegerSchema(schema) || ModelUtils.isNumberSchema(schema) || ModelUtils.isStringSchema(schema)) {
// TODO convert oneOf const to enum
Expand Down Expand Up @@ -1445,7 +1444,7 @@ protected Schema processSimplifyAnyOf(Schema schema) {
}
}

schema = simplyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, schema, anyOfSchemas);
schema = simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, schema, anyOfSchemas);
}

return schema;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2227,17 +2227,24 @@ public static Schema cloneSchema(Schema schema, boolean openapi31) {
* @param subSchemas The oneOf or AnyOf schemas
* @return The simplified schema
*/
public static Schema simplyOneOfAnyOfWithOnlyOneNonNullSubSchema(OpenAPI openAPI, Schema schema, List<Schema> subSchemas) {
public static Schema simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema(OpenAPI openAPI, Schema schema, List<Schema> subSchemas) {
if (subSchemas.removeIf(subSchema -> isNullTypeSchema(openAPI, subSchema))) {
schema.setNullable(true);
}

// if only one element left, simplify to just the element (schema)
if (subSchemas.size() == 1) {
Schema<?> subSchema = subSchemas.get(0);
if (Boolean.TRUE.equals(schema.getNullable())) { // retain nullable setting
subSchemas.get(0).setNullable(true);
subSchema.setNullable(true);
}
return subSchemas.get(0);
if (Boolean.TRUE.equals(schema.getReadOnly())) {
subSchema.setReadOnly(true);
}
if (Boolean.TRUE.equals(schema.getWriteOnly())) {
subSchema.setWriteOnly(true);
}
return subSchema;
}

return schema;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -476,53 +476,109 @@ public void testGetSchemaItemsWith31Spec() {
}

@Test
public void simplyOneOfAnyOfWithOnlyOneNonNullSubSchema() {
public void simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema() {
OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/simplifyOneOfAnyOf_test.yaml");
Schema schema;
List<Schema> subSchemas;

Schema anyOfWithSeveralSubSchemasButSingleNonNull = ModelUtils.getSchema(openAPI, "AnyOfTest");
subSchemas = anyOfWithSeveralSubSchemasButSingleNonNull.getAnyOf();
schema = ModelUtils.simplyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, anyOfWithSeveralSubSchemasButSingleNonNull, subSchemas);
schema = ModelUtils.simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, anyOfWithSeveralSubSchemasButSingleNonNull, subSchemas);
assertNull(schema.getOneOf());
assertNull(schema.getAnyOf());
assertTrue(schema.getNullable());
assertEquals("string", schema.getType());

Schema anyOfWithSingleNonNullSubSchema = ModelUtils.getSchema(openAPI, "Parent");
subSchemas = ((Schema) anyOfWithSingleNonNullSubSchema.getProperties().get("number")).getAnyOf();
schema = ModelUtils.simplyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, anyOfWithSingleNonNullSubSchema, subSchemas);
schema = ModelUtils.simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, anyOfWithSingleNonNullSubSchema, subSchemas);
assertNull(schema.getOneOf());
assertNull(schema.getAnyOf());
assertNull(schema.getNullable());
assertEquals(schema.get$ref(), "#/components/schemas/Number");

Schema oneOfWithSeveralSubSchemasButSingleNonNull = ModelUtils.getSchema(openAPI, "OneOfTest");
subSchemas = oneOfWithSeveralSubSchemasButSingleNonNull.getOneOf();
schema = ModelUtils.simplyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, oneOfWithSeveralSubSchemasButSingleNonNull, subSchemas);
schema = ModelUtils.simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, oneOfWithSeveralSubSchemasButSingleNonNull, subSchemas);
assertNull(schema.getOneOf());
assertNull(schema.getAnyOf());
assertTrue(schema.getNullable());
assertEquals("integer", schema.getType());

Schema oneOfWithSingleNonNullSubSchema = ModelUtils.getSchema(openAPI, "ParentWithOneOfProperty");
subSchemas = ((Schema) oneOfWithSingleNonNullSubSchema.getProperties().get("number")).getOneOf();
schema = ModelUtils.simplyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, oneOfWithSingleNonNullSubSchema, subSchemas);
schema = ModelUtils.simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, oneOfWithSingleNonNullSubSchema, subSchemas);
assertNull(schema.getOneOf());
assertNull(schema.getAnyOf());
assertNull(schema.getNullable());
assertEquals(schema.get$ref(), "#/components/schemas/Number");

Schema oneOfWithSeveralSubSchemas = ModelUtils.getSchema(openAPI, "ParentWithPluralOneOfProperty");
subSchemas = ((Schema) oneOfWithSeveralSubSchemas.getProperties().get("number")).getOneOf();
schema = ModelUtils.simplyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, oneOfWithSeveralSubSchemas, subSchemas);
schema = ModelUtils.simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, oneOfWithSeveralSubSchemas, subSchemas);
assertNull(schema.getOneOf());
assertNotNull(oneOfWithSeveralSubSchemas.getProperties().get("number"));
assertNull(schema.getAnyOf());
assertNull(schema.getNullable());
assertEquals(((Schema) oneOfWithSeveralSubSchemas.getProperties().get("number")).getOneOf().size(), 2);
}

@Test
public void simplifyOneOfWithOnlyOneNonNullSubSchemaKeepsReadOnlyWriteOnlyAttribute() {
OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/simplifyOneOfAnyOf_test.yaml");
Schema schema;
List<Schema> subSchemas;

Schema oneOfWithNullAndRefSubSchema = ModelUtils.getSchema(openAPI, "OneOfParentRefTest");
Schema numberPropertySchema = ((Schema) oneOfWithNullAndRefSubSchema.getProperties().get("number"));
subSchemas = numberPropertySchema.getOneOf();
schema = ModelUtils.simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, numberPropertySchema, subSchemas);
assertNull(schema.getOneOf());
assertNull(schema.getAnyOf());
assertTrue(schema.getNullable());
assertNull(schema.getReadOnly());
assertTrue(schema.getWriteOnly());
assertEquals(schema.get$ref(), "#/components/schemas/IntegerRef");

Schema number2PropertySchema = ((Schema) oneOfWithNullAndRefSubSchema.getProperties().get("number2"));
subSchemas = number2PropertySchema.getOneOf();
schema = ModelUtils.simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, number2PropertySchema, subSchemas);
assertNull(schema.getOneOf());
assertNull(schema.getAnyOf());
assertTrue(schema.getNullable());
assertTrue(schema.getReadOnly());
assertNull(schema.getWriteOnly());
assertEquals(schema.get$ref(), "#/components/schemas/IntegerRef");
}

@Test
public void simplifyAnyOfWithOnlyOneNonNullSubSchemaKeepsReadOnlyWriteOnlyAttribute() {
OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/simplifyOneOfAnyOf_test.yaml");
Schema schema;
List<Schema> subSchemas;

Schema anyOfWithNullAndRefSubSchema = ModelUtils.getSchema(openAPI, "AnyOfParentRefTest");
Schema numberPropertySchema = ((Schema) anyOfWithNullAndRefSubSchema.getProperties().get("number"));
subSchemas = numberPropertySchema.getAnyOf();
schema = ModelUtils.simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, numberPropertySchema, subSchemas);
assertNull(schema.getOneOf());
assertNull(schema.getAnyOf());
assertTrue(schema.getNullable());
assertNull(schema.getReadOnly());
assertTrue(schema.getWriteOnly());
assertEquals(schema.get$ref(), "#/components/schemas/IntegerRef");

Schema number2PropertySchema = ((Schema) anyOfWithNullAndRefSubSchema.getProperties().get("number2"));
subSchemas = number2PropertySchema.getAnyOf();
schema = ModelUtils.simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, number2PropertySchema, subSchemas);
assertNull(schema.getOneOf());
assertNull(schema.getAnyOf());
assertTrue(schema.getNullable());
assertTrue(schema.getReadOnly());
assertNull(schema.getWriteOnly());
assertEquals(schema.get$ref(), "#/components/schemas/IntegerRef");
}

@Test
public void isNullTypeSchemaTest() {
OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/null_schema_test.yaml");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,30 @@ components:
- type: string
- type: integer
- type: array
items: {}
items: {}
AnyOfParentRefTest:
type: object
properties:
number:
anyOf:
- type: null
- $ref: '#/components/schemas/IntegerRef'
writeOnly: true
number2:
anyOf:
- type: null
- $ref: '#/components/schemas/IntegerRef'
readOnly: true
OneOfParentRefTest:
type: object
properties:
number:
oneOf:
- type: null
- $ref: '#/components/schemas/IntegerRef'
writeOnly: true
number2:
oneOf:
- type: null
- $ref: '#/components/schemas/IntegerRef'
readOnly: true
Loading