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 @@ -515,6 +515,7 @@ public static enum ENUM_PROPERTY_NAMING_TYPE {camelCase, PascalCase, snake_case,
public static final String X_NULLABLE = "x-nullable";
public static final String X_ENUM_VARNAMES = "x-enum-varnames";
public static final String X_ENUM_DESCRIPTIONS = "x-enum-descriptions";
public static final String X_ENUM_DEPRECATED = "x-enum-deprecated";
public static final String X_PY_TYPING = "x-py-typing";
public static final String X_PY_EXAMPLE = "x-py-example";
public static final String X_PY_EXAMPLE_IMPORT = "x-py-example-import";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@
import io.swagger.v3.oas.models.responses.ApiResponse;
import io.swagger.v3.oas.models.responses.ApiResponses;
import io.swagger.v3.oas.models.security.SecurityScheme;
import io.swagger.v3.oas.models.security.SecurityScheme.Type;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.utils.EnumUtils;
import org.openapitools.codegen.utils.ModelUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -1642,8 +1642,7 @@ protected Schema processSimplifyOneOfEnum(Schema schema) {
* @return Simplified schema
*/
protected Schema simplifyComposedSchemaWithEnums(Schema schema, List<Object> subSchemas, String composedType) {
Map<Object, String> enumValues = new LinkedHashMap<>();
Map<Object, Boolean> deprecatedValues = new LinkedHashMap<>();
Map<Object, EnumUtils.EnumExtensions> enumExtensions = new LinkedHashMap<>();

if(schema.getTypes() != null && schema.getTypes().size() > 1) {
// we cannot handle enums with multiple types
Expand Down Expand Up @@ -1697,53 +1696,35 @@ protected Schema simplifyComposedSchemaWithEnums(Schema schema, List<Object> sub
}
description += subSchema.getDescription();
}
enumValues.put(subSchemaEnumValues.get(0), description);
deprecatedValues.put(subSchemaEnumValues.get(0), subSchemaDeprecated);
enumExtensions.put(subSchemaEnumValues.get(0), new EnumUtils.EnumExtensions(description, subSchemaDeprecated));
} else {
for(Object e: subSchemaEnumValues) {
enumValues.put(e, "");
deprecatedValues.put(e, subSchemaDeprecated);
enumExtensions.put(e, new EnumUtils.EnumExtensions("", subSchemaDeprecated));
}
}

}

return createSimplifiedEnumSchema(schema, enumValues, deprecatedValues, schemaType, composedType);
return createSimplifiedEnumSchema(schema, enumExtensions, schemaType, composedType);
}


/**
* Creates a simplified enum schema from collected enum values.
*
* @param originalSchema Original schema to modify
* @param enumValues Collected enum values
* @param deprecatedValues Per-value deprecated flags (aligned with enumValues key order)
* @param enumExtensions Collected enum values
* @param schemaType Consistent type across sub-schemas
* @param composedType Type of composed schema being simplified
* @return Simplified enum schema
*/
protected Schema createSimplifiedEnumSchema(Schema originalSchema, Map<Object, String> enumValues, Map<Object, Boolean> deprecatedValues, String schemaType, String composedType) {
protected Schema createSimplifiedEnumSchema(Schema originalSchema, Map<Object, EnumUtils.EnumExtensions> enumExtensions, String schemaType, String composedType) {
// Clear the composed schema type
if ("oneOf".equals(composedType)) {
originalSchema.setOneOf(null);
} else if ("anyOf".equals(composedType)) {
originalSchema.setAnyOf(null);
}

if (ModelUtils.getType(originalSchema) == null && schemaType != null) {
//if type was specified in subschemas, keep it in the main schema
ModelUtils.setType(originalSchema, schemaType);
}

originalSchema.setEnum(new ArrayList<>(enumValues.keySet()));
if(enumValues.values().stream().anyMatch(e -> !e.isEmpty())) {
//set x-enum-descriptions only if there's at least one non-empty description
originalSchema.addExtension(X_ENUM_DESCRIPTIONS, new ArrayList<>(enumValues.values()));
}
if (deprecatedValues != null && deprecatedValues.values().stream().anyMatch(Boolean.TRUE::equals)) {
// preserve per-value deprecated flags from OAS 3.1 oneOf/anyOf + const sub-schemas
originalSchema.addExtension("x-enum-deprecated", new ArrayList<>(deprecatedValues.values()));
}
EnumUtils.createSimplifiedEnumSchema(originalSchema, enumExtensions, schemaType);

LOGGER.debug("Simplified {} with enum sub-schemas to single enum: {}", composedType, originalSchema);

Expand Down Expand Up @@ -1835,7 +1816,7 @@ protected Schema processReplaceOneOfByMapping(Schema schema) {
return schema;
}
Map<String, String> mappings = new TreeMap<>();
// is the discriminator qttribute qlready in this schema?
// is the discriminator attribute already in this schema?
// if yes, it will be deleted in references oneOf to avoid duplicates
boolean hasProperty = findProperty(schema, discriminator.getPropertyName(), false, new HashSet<>()) != null;
discriminator.setMapping(mappings);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package org.openapitools.codegen.utils;

import io.swagger.v3.oas.models.media.Schema;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static org.openapitools.codegen.CodegenConstants.X_ENUM_DEPRECATED;
import static org.openapitools.codegen.CodegenConstants.X_ENUM_DESCRIPTIONS;

public class EnumUtils {

public static Schema createSimplifiedEnumSchema(Schema originalSchema,
Map<Object, EnumExtensions> enums,
String schemaType) {
if (ModelUtils.getType(originalSchema) == null && schemaType != null) {
//if type was specified in subschemas, keep it in the main schema
ModelUtils.setType(originalSchema, schemaType);
}

originalSchema.setEnum(new ArrayList<>(enums.keySet()));
List<String> enumDescriptions = enums.values().stream().map(EnumExtensions::getDescription).collect(Collectors.toList());
List<Boolean> enumDeprecations = enums.values().stream().map(EnumExtensions::isDeprecated).collect(Collectors.toList());
if(enumDescriptions.stream().anyMatch(e -> !e.isEmpty())) {
//set x-enum-descriptions only if there's at least one non-empty description
originalSchema.addExtension(X_ENUM_DESCRIPTIONS, new ArrayList<>(enumDescriptions));
}
if (enumDeprecations.stream().anyMatch(Boolean.TRUE::equals)) {
// preserve per-value deprecated flags from OAS 3.1 oneOf/anyOf + const sub-schemas
originalSchema.addExtension(X_ENUM_DEPRECATED, new ArrayList<>(enumDeprecations));
}

return originalSchema;
}

public static class EnumExtensions {
private final String description;
private final boolean deprecated;

public EnumExtensions(String description, boolean deprecated) {
this.description = description;
this.deprecated = deprecated;
}

public String getDescription() {
return description;
}

public boolean isDeprecated() {
return deprecated;
}
}

}
Loading