Skip to content

Commit 490de02

Browse files
Fix so that the oneOfAnyOf normalizer retains the read/write only attribute (#21737)
1 parent 3ebb299 commit 490de02

File tree

4 files changed

+102
-14
lines changed

4 files changed

+102
-14
lines changed

modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,11 @@
3333
import org.slf4j.LoggerFactory;
3434

3535
import java.lang.reflect.Constructor;
36-
import java.lang.reflect.InvocationTargetException;
3736
import java.util.*;
3837
import java.util.function.Function;
3938
import java.util.stream.Collectors;
4039

41-
import static org.openapitools.codegen.utils.ModelUtils.simplyOneOfAnyOfWithOnlyOneNonNullSubSchema;
40+
import static org.openapitools.codegen.utils.ModelUtils.simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema;
4241
import static org.openapitools.codegen.utils.StringUtils.getUniqueString;
4342

4443
public class OpenAPINormalizer {
@@ -1318,7 +1317,7 @@ protected Schema processSimplifyOneOf(Schema schema) {
13181317
}
13191318
}
13201319

1321-
schema = simplyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, schema, oneOfSchemas);
1320+
schema = simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, schema, oneOfSchemas);
13221321

13231322
if (ModelUtils.isIntegerSchema(schema) || ModelUtils.isNumberSchema(schema) || ModelUtils.isStringSchema(schema)) {
13241323
// TODO convert oneOf const to enum
@@ -1445,7 +1444,7 @@ protected Schema processSimplifyAnyOf(Schema schema) {
14451444
}
14461445
}
14471446

1448-
schema = simplyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, schema, anyOfSchemas);
1447+
schema = simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, schema, anyOfSchemas);
14491448
}
14501449

14511450
return schema;

modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2227,17 +2227,24 @@ public static Schema cloneSchema(Schema schema, boolean openapi31) {
22272227
* @param subSchemas The oneOf or AnyOf schemas
22282228
* @return The simplified schema
22292229
*/
2230-
public static Schema simplyOneOfAnyOfWithOnlyOneNonNullSubSchema(OpenAPI openAPI, Schema schema, List<Schema> subSchemas) {
2230+
public static Schema simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema(OpenAPI openAPI, Schema schema, List<Schema> subSchemas) {
22312231
if (subSchemas.removeIf(subSchema -> isNullTypeSchema(openAPI, subSchema))) {
22322232
schema.setNullable(true);
22332233
}
22342234

22352235
// if only one element left, simplify to just the element (schema)
22362236
if (subSchemas.size() == 1) {
2237+
Schema<?> subSchema = subSchemas.get(0);
22372238
if (Boolean.TRUE.equals(schema.getNullable())) { // retain nullable setting
2238-
subSchemas.get(0).setNullable(true);
2239+
subSchema.setNullable(true);
22392240
}
2240-
return subSchemas.get(0);
2241+
if (Boolean.TRUE.equals(schema.getReadOnly())) {
2242+
subSchema.setReadOnly(true);
2243+
}
2244+
if (Boolean.TRUE.equals(schema.getWriteOnly())) {
2245+
subSchema.setWriteOnly(true);
2246+
}
2247+
return subSchema;
22412248
}
22422249

22432250
return schema;

modules/openapi-generator/src/test/java/org/openapitools/codegen/utils/ModelUtilsTest.java

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -476,53 +476,109 @@ public void testGetSchemaItemsWith31Spec() {
476476
}
477477

478478
@Test
479-
public void simplyOneOfAnyOfWithOnlyOneNonNullSubSchema() {
479+
public void simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema() {
480480
OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/simplifyOneOfAnyOf_test.yaml");
481481
Schema schema;
482482
List<Schema> subSchemas;
483483

484484
Schema anyOfWithSeveralSubSchemasButSingleNonNull = ModelUtils.getSchema(openAPI, "AnyOfTest");
485485
subSchemas = anyOfWithSeveralSubSchemasButSingleNonNull.getAnyOf();
486-
schema = ModelUtils.simplyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, anyOfWithSeveralSubSchemasButSingleNonNull, subSchemas);
486+
schema = ModelUtils.simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, anyOfWithSeveralSubSchemasButSingleNonNull, subSchemas);
487487
assertNull(schema.getOneOf());
488488
assertNull(schema.getAnyOf());
489489
assertTrue(schema.getNullable());
490490
assertEquals("string", schema.getType());
491491

492492
Schema anyOfWithSingleNonNullSubSchema = ModelUtils.getSchema(openAPI, "Parent");
493493
subSchemas = ((Schema) anyOfWithSingleNonNullSubSchema.getProperties().get("number")).getAnyOf();
494-
schema = ModelUtils.simplyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, anyOfWithSingleNonNullSubSchema, subSchemas);
494+
schema = ModelUtils.simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, anyOfWithSingleNonNullSubSchema, subSchemas);
495495
assertNull(schema.getOneOf());
496496
assertNull(schema.getAnyOf());
497497
assertNull(schema.getNullable());
498498
assertEquals(schema.get$ref(), "#/components/schemas/Number");
499499

500500
Schema oneOfWithSeveralSubSchemasButSingleNonNull = ModelUtils.getSchema(openAPI, "OneOfTest");
501501
subSchemas = oneOfWithSeveralSubSchemasButSingleNonNull.getOneOf();
502-
schema = ModelUtils.simplyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, oneOfWithSeveralSubSchemasButSingleNonNull, subSchemas);
502+
schema = ModelUtils.simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, oneOfWithSeveralSubSchemasButSingleNonNull, subSchemas);
503503
assertNull(schema.getOneOf());
504504
assertNull(schema.getAnyOf());
505505
assertTrue(schema.getNullable());
506506
assertEquals("integer", schema.getType());
507507

508508
Schema oneOfWithSingleNonNullSubSchema = ModelUtils.getSchema(openAPI, "ParentWithOneOfProperty");
509509
subSchemas = ((Schema) oneOfWithSingleNonNullSubSchema.getProperties().get("number")).getOneOf();
510-
schema = ModelUtils.simplyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, oneOfWithSingleNonNullSubSchema, subSchemas);
510+
schema = ModelUtils.simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, oneOfWithSingleNonNullSubSchema, subSchemas);
511511
assertNull(schema.getOneOf());
512512
assertNull(schema.getAnyOf());
513513
assertNull(schema.getNullable());
514514
assertEquals(schema.get$ref(), "#/components/schemas/Number");
515515

516516
Schema oneOfWithSeveralSubSchemas = ModelUtils.getSchema(openAPI, "ParentWithPluralOneOfProperty");
517517
subSchemas = ((Schema) oneOfWithSeveralSubSchemas.getProperties().get("number")).getOneOf();
518-
schema = ModelUtils.simplyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, oneOfWithSeveralSubSchemas, subSchemas);
518+
schema = ModelUtils.simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, oneOfWithSeveralSubSchemas, subSchemas);
519519
assertNull(schema.getOneOf());
520520
assertNotNull(oneOfWithSeveralSubSchemas.getProperties().get("number"));
521521
assertNull(schema.getAnyOf());
522522
assertNull(schema.getNullable());
523523
assertEquals(((Schema) oneOfWithSeveralSubSchemas.getProperties().get("number")).getOneOf().size(), 2);
524524
}
525525

526+
@Test
527+
public void simplifyOneOfWithOnlyOneNonNullSubSchemaKeepsReadOnlyWriteOnlyAttribute() {
528+
OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/simplifyOneOfAnyOf_test.yaml");
529+
Schema schema;
530+
List<Schema> subSchemas;
531+
532+
Schema oneOfWithNullAndRefSubSchema = ModelUtils.getSchema(openAPI, "OneOfParentRefTest");
533+
Schema numberPropertySchema = ((Schema) oneOfWithNullAndRefSubSchema.getProperties().get("number"));
534+
subSchemas = numberPropertySchema.getOneOf();
535+
schema = ModelUtils.simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, numberPropertySchema, subSchemas);
536+
assertNull(schema.getOneOf());
537+
assertNull(schema.getAnyOf());
538+
assertTrue(schema.getNullable());
539+
assertNull(schema.getReadOnly());
540+
assertTrue(schema.getWriteOnly());
541+
assertEquals(schema.get$ref(), "#/components/schemas/IntegerRef");
542+
543+
Schema number2PropertySchema = ((Schema) oneOfWithNullAndRefSubSchema.getProperties().get("number2"));
544+
subSchemas = number2PropertySchema.getOneOf();
545+
schema = ModelUtils.simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, number2PropertySchema, subSchemas);
546+
assertNull(schema.getOneOf());
547+
assertNull(schema.getAnyOf());
548+
assertTrue(schema.getNullable());
549+
assertTrue(schema.getReadOnly());
550+
assertNull(schema.getWriteOnly());
551+
assertEquals(schema.get$ref(), "#/components/schemas/IntegerRef");
552+
}
553+
554+
@Test
555+
public void simplifyAnyOfWithOnlyOneNonNullSubSchemaKeepsReadOnlyWriteOnlyAttribute() {
556+
OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/simplifyOneOfAnyOf_test.yaml");
557+
Schema schema;
558+
List<Schema> subSchemas;
559+
560+
Schema anyOfWithNullAndRefSubSchema = ModelUtils.getSchema(openAPI, "AnyOfParentRefTest");
561+
Schema numberPropertySchema = ((Schema) anyOfWithNullAndRefSubSchema.getProperties().get("number"));
562+
subSchemas = numberPropertySchema.getAnyOf();
563+
schema = ModelUtils.simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, numberPropertySchema, subSchemas);
564+
assertNull(schema.getOneOf());
565+
assertNull(schema.getAnyOf());
566+
assertTrue(schema.getNullable());
567+
assertNull(schema.getReadOnly());
568+
assertTrue(schema.getWriteOnly());
569+
assertEquals(schema.get$ref(), "#/components/schemas/IntegerRef");
570+
571+
Schema number2PropertySchema = ((Schema) anyOfWithNullAndRefSubSchema.getProperties().get("number2"));
572+
subSchemas = number2PropertySchema.getAnyOf();
573+
schema = ModelUtils.simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, number2PropertySchema, subSchemas);
574+
assertNull(schema.getOneOf());
575+
assertNull(schema.getAnyOf());
576+
assertTrue(schema.getNullable());
577+
assertTrue(schema.getReadOnly());
578+
assertNull(schema.getWriteOnly());
579+
assertEquals(schema.get$ref(), "#/components/schemas/IntegerRef");
580+
}
581+
526582
@Test
527583
public void isNullTypeSchemaTest() {
528584
OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/null_schema_test.yaml");

modules/openapi-generator/src/test/resources/3_0/simplifyOneOfAnyOf_test.yaml

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,30 @@ components:
122122
- type: string
123123
- type: integer
124124
- type: array
125-
items: {}
125+
items: {}
126+
AnyOfParentRefTest:
127+
type: object
128+
properties:
129+
number:
130+
anyOf:
131+
- type: null
132+
- $ref: '#/components/schemas/IntegerRef'
133+
writeOnly: true
134+
number2:
135+
anyOf:
136+
- type: null
137+
- $ref: '#/components/schemas/IntegerRef'
138+
readOnly: true
139+
OneOfParentRefTest:
140+
type: object
141+
properties:
142+
number:
143+
oneOf:
144+
- type: null
145+
- $ref: '#/components/schemas/IntegerRef'
146+
writeOnly: true
147+
number2:
148+
oneOf:
149+
- type: null
150+
- $ref: '#/components/schemas/IntegerRef'
151+
readOnly: true

0 commit comments

Comments
 (0)