Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add rule to simplify boolean enum #14764

Merged
merged 2 commits into from
Feb 21, 2023
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
7 changes: 7 additions & 0 deletions docs/customization.md
Original file line number Diff line number Diff line change
Expand Up @@ -477,3 +477,10 @@ Example:
```
java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i modules/openapi-generator/src/test/resources/3_0/simplifyAnyOfStringAndEnumString_test.yaml -o /tmp/java-okhttp/ --openapi-normalizer SIMPLIFY_ANYOF_STRING_AND_ENUM_STRING=true
```

- `SIMPLIFY_BOOLEAN_ENUM`: when set to `true`, convert boolean enum to just enum.

Example:
```
java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i modules/openapi-generator/src/test/resources/3_0/simplifyBooleanEnum_test.yaml -o /tmp/java-okhttp/ --openapi-normalizer SIMPLIFY_BOOLEAN_ENUM=true
```
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ public class OpenAPINormalizer {
final String SIMPLIFY_ANYOF_STRING_AND_ENUM_STRING = "SIMPLIFY_ANYOF_STRING_AND_ENUM_STRING";
boolean simplifyAnyOfStringAndEnumString;

// when set to true, boolean enum will be converted to just boolean
final String SIMPLIFY_BOOLEAN_ENUM = "SIMPLIFY_BOOLEAN_ENUM";
boolean simplifyBooleanEnum;

// ============= end of rules =============

/**
Expand Down Expand Up @@ -106,6 +110,10 @@ public void parseRules(Map<String, String> rules) {
if (enableAll || "true".equalsIgnoreCase(rules.get(SIMPLIFY_ANYOF_STRING_AND_ENUM_STRING))) {
simplifyAnyOfStringAndEnumString = true;
}

if (enableAll || "true".equalsIgnoreCase(rules.get(SIMPLIFY_BOOLEAN_ENUM))) {
simplifyBooleanEnum = true;
}
}

/**
Expand Down Expand Up @@ -301,11 +309,11 @@ public Schema normalizeSchema(Schema schema, Set<Schema> visitedSchemas) {
visitedSchemas.add(schema);
}

if (schema instanceof ArraySchema) {
if (schema instanceof ArraySchema) { // array
normalizeSchema(schema.getItems(), visitedSchemas);
} else if (schema.getAdditionalProperties() instanceof Schema) { // map
normalizeSchema((Schema) schema.getAdditionalProperties(), visitedSchemas);
} else if (ModelUtils.isComposedSchema(schema)) {
} else if (ModelUtils.isComposedSchema(schema)) { // composed schema
ComposedSchema cs = (ComposedSchema) schema;

if (ModelUtils.isComplexComposedSchema(cs)) {
Expand Down Expand Up @@ -337,6 +345,8 @@ public Schema normalizeSchema(Schema schema, Set<Schema> visitedSchemas) {
normalizeSchema(schema.getNot(), visitedSchemas);
} else if (schema.getProperties() != null && !schema.getProperties().isEmpty()) {
normalizeProperties(schema.getProperties(), visitedSchemas);
} else if (schema instanceof BooleanSchema) {
normalizeBooleanSchema(schema, visitedSchemas);
} else if (schema instanceof Schema) {
normalizeSchemaWithOnlyProperties(schema, visitedSchemas);
} else {
Expand All @@ -346,6 +356,10 @@ public Schema normalizeSchema(Schema schema, Set<Schema> visitedSchemas) {
return schema;
}

private void normalizeBooleanSchema(Schema schema, Set<Schema> visitedSchemas) {
processSimplifyBooleanEnum(schema);
}

private void normalizeSchemaWithOnlyProperties(Schema schema, Set<Schema> visitedSchemas) {
// normalize non-composed schema (e.g. schema with only properties)
}
Expand Down Expand Up @@ -476,7 +490,6 @@ private void processKeepOnlyFirstTagInOperation(Operation operation) {
* @param schema Schema
*/
private void processRemoveAnyOfOneOfAndKeepPropertiesOnly(Schema schema) {

if (!removeAnyOfOneOfAndKeepPropertiesOnly && !enableAll) {
return;
}
Expand Down Expand Up @@ -528,5 +541,25 @@ private Schema processSimplifyAnyOfStringAndEnumString(Schema schema) {
}
}

/**
* If the schema is boolean and its enum is defined,
* then simply it to just boolean.
*
* @param schema Schema
* @return Schema
*/
private void processSimplifyBooleanEnum(Schema schema) {
if (!simplifyBooleanEnum && !enableAll) {
return;
}

if (schema instanceof BooleanSchema) {
BooleanSchema bs = (BooleanSchema) schema;
if (bs.getEnum() != null && !bs.getEnum().isEmpty()) { // enum defined
bs.setEnum(null);
}
}
}

// ===================== end of rules =====================
}
Original file line number Diff line number Diff line change
Expand Up @@ -4394,4 +4394,27 @@ public void testOpenAPINormalizerSimplifyOneOfAnyOfStringAndEnumString() {
assertNull(schema3.getAnyOf());
assertTrue(schema3 instanceof StringSchema);
}

@Test
public void testOpenAPINormalizerSimplifyBooleanEnum() {
// to test the rule SIMPLIFY_BOOLEAN_ENUM
OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/simplifyBooleanEnum_test.yaml");

Schema schema = openAPI.getComponents().getSchemas().get("BooleanEnumTest");
assertEquals(schema.getProperties().size(), 3);
assertTrue(schema.getProperties().get("boolean_enum") instanceof BooleanSchema);
BooleanSchema bs = (BooleanSchema) schema.getProperties().get("boolean_enum");
assertEquals(bs.getEnum().size(), 2);

Map<String, String> options = new HashMap<>();
options.put("SIMPLIFY_BOOLEAN_ENUM", "true");
OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options);
openAPINormalizer.normalize();

Schema schema3 = openAPI.getComponents().getSchemas().get("BooleanEnumTest");
assertEquals(schema.getProperties().size(), 3);
assertTrue(schema.getProperties().get("boolean_enum") instanceof BooleanSchema);
BooleanSchema bs2 = (BooleanSchema) schema.getProperties().get("boolean_enum");
assertNull(bs2.getEnum()); //ensure the enum has been erased
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
openapi: 3.0.1
info:
version: 1.0.0
title: Example
license:
name: MIT
servers:
- url: http://api.example.xyz/v1
paths:
/person/display/{personId}:
get:
parameters:
- name: personId
in: path
required: true
description: The id of the person to retrieve
schema:
type: string
operationId: list
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/BooleanEnumTest"
components:
schemas:
BooleanEnumTest:
description: a model to with boolean enum property
type: object
properties:
id:
type: integer
format: int64
name:
type: string
pattern: '^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$'
boolean_enum:
type: boolean
enum:
- true
- false