-
-
Notifications
You must be signed in to change notification settings - Fork 7.4k
[Java][Spring] fix one of #10463
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
[Java][Spring] fix one of #10463
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -43,6 +43,7 @@ | |
| import java.util.regex.Pattern; | ||
| import java.util.stream.Stream; | ||
|
|
||
| import io.swagger.v3.oas.models.responses.ApiResponse; | ||
| import org.apache.commons.io.FilenameUtils; | ||
| import org.apache.commons.lang3.BooleanUtils; | ||
| import org.apache.commons.lang3.StringUtils; | ||
|
|
@@ -1363,8 +1364,23 @@ public void preprocessOpenAPI(OpenAPI openAPI) { | |
| } | ||
| for (Operation operation : path.readOperations()) { | ||
| LOGGER.info("Processing operation {}", operation.getOperationId()); | ||
| if (hasBodyParameter(openAPI, operation) || hasFormParameter(openAPI, operation)) { | ||
| String defaultContentType = hasFormParameter(openAPI, operation) ? "application/x-www-form-urlencoded" : "application/json"; | ||
| boolean hasBodyParameter = hasBodyParameter(openAPI, operation); | ||
| boolean hasFormParameter = hasFormParameter(openAPI, operation); | ||
|
|
||
| // OpenAPI parser do not add Inline One Of models in Operations to Components/Schemas | ||
| if (hasBodyParameter) { | ||
| Optional.ofNullable(operation.getRequestBody()) | ||
| .map(RequestBody::getContent) | ||
| .ifPresent(this::repairInlineOneOf); | ||
| } | ||
| if (operation.getResponses() != null) { | ||
| operation.getResponses().values().stream().map(ApiResponse::getContent) | ||
| .filter(Objects::nonNull) | ||
| .forEach(this::repairInlineOneOf); | ||
| } | ||
|
|
||
| if (hasBodyParameter || hasFormParameter) { | ||
| String defaultContentType = hasFormParameter ? "application/x-www-form-urlencoded" : "application/json"; | ||
| List<String> consumes = new ArrayList<>(getConsumesInfo(openAPI, operation)); | ||
| String contentType = consumes == null || consumes.isEmpty() ? defaultContentType : consumes.get(0); | ||
| operation.addExtension("x-contentType", contentType); | ||
|
|
@@ -1421,6 +1437,39 @@ public void preprocessOpenAPI(OpenAPI openAPI) { | |
| } | ||
| } | ||
|
|
||
| /** | ||
| * Add all OneOf schemas to #/components/schemas and replace them in the original content by ref schema | ||
| * Replace OneOf with unmodifiable types with an empty Schema | ||
| * | ||
| * OpenAPI Parser does not add inline OneOf schemas to models to generate | ||
| * | ||
| * @param content a 'content' section in the OAS specification. | ||
| */ | ||
| private void repairInlineOneOf(final Content content) { | ||
| content.values().forEach(mediaType -> { | ||
| final Schema replacingSchema = mediaType.getSchema(); | ||
| if (isOneOfSchema(replacingSchema)) { | ||
| if (ModelUtils.isSchemaOneOfConsistsOfCustomTypes(openAPI, replacingSchema)) { | ||
| final String oneOfModelName = (String) replacingSchema.getExtensions().get("x-one-of-name"); | ||
| final Schema newRefSchema = new Schema<>().$ref("#/components/schemas/" + oneOfModelName); | ||
| mediaType.setSchema(newRefSchema); | ||
| ModelUtils.getSchemas(openAPI).put(oneOfModelName, replacingSchema); | ||
| } else { | ||
| mediaType.setSchema(new Schema()); | ||
| } | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| private static boolean isOneOfSchema(final Schema schema) { | ||
| if (schema instanceof ComposedSchema) { | ||
| ComposedSchema composedSchema = (ComposedSchema) schema; | ||
| return Optional.ofNullable(composedSchema.getProperties()).map(Map::isEmpty).orElse(true) | ||
| && Optional.ofNullable(schema.getExtensions()).map(m -> m.containsKey("x-one-of-name")).orElse(false); | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FYI. Since these changes occur in the abstract java codegen, which is used by the java client codegen, we will need to test the Java client (jersey2, native) generator carefully which already supports oneOf implementation (not using interface though) Have you tried the oneOf implementation in Java client (jersey2, native) generator? Does it meet your requirement? |
||
| private static String getAccept(OpenAPI openAPI, Operation operation) { | ||
| String accepts = null; | ||
| String defaultContentType = "application/json"; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| {{>additionalModelTypeAnnotations}}{{>generatedAnnotation}}{{>typeInfoAnnotation}}{{>xmlAnnotation}} | ||
| public interface {{classname}} {{#vendorExtensions.x-implements}}{{#-first}}extends {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{/vendorExtensions.x-implements}} { | ||
| {{#discriminator}} | ||
| {{^vendorExtensions.x-deduction}}{{#discriminator}} | ||
| public {{propertyType}} {{propertyGetter}}(); | ||
| {{/discriminator}} | ||
| {{/discriminator}}{{/vendorExtensions.x-deduction}} | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| {{>additionalModelTypeAnnotations}}{{>generatedAnnotation}}{{>typeInfoAnnotation}}{{>xmlAnnotation}} | ||
| public interface {{classname}} {{#vendorExtensions.x-implements}}{{#-first}}extends {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{/vendorExtensions.x-implements}} { | ||
| {{^vendorExtensions.x-deduction}}{{#discriminator}} | ||
| public {{propertyType}} {{propertyGetter}}(); | ||
| {{/discriminator}}{{/vendorExtensions.x-deduction}} | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| {{>additionalModelTypeAnnotations}}{{>generatedAnnotation}}{{>typeInfoAnnotation}}{{>xmlAnnotation}} | ||
| public interface {{classname}} {{#vendorExtensions.x-implements}}{{#-first}}extends {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{/vendorExtensions.x-implements}} { | ||
| {{^vendorExtensions.x-deduction}}{{#discriminator}} | ||
| public {{propertyType}} {{propertyGetter}}(); | ||
| {{/discriminator}}{{/vendorExtensions.x-deduction}} | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,14 @@ | ||
| {{#jackson}} | ||
|
|
||
| {{^vendorExtensions.x-deduction}} | ||
| @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "{{{discriminator.propertyBaseName}}}", visible = true) | ||
| {{/vendorExtensions.x-deduction}}{{#vendorExtensions.x-deduction}} | ||
| @JsonTypeInfo(use = JsonTypeInfo.Id.DEDUCTION){{/vendorExtensions.x-deduction}} | ||
| @JsonSubTypes({ | ||
| {{#discriminator.mappedModels}} | ||
| @JsonSubTypes.Type(value = {{modelName}}.class, name = "{{^vendorExtensions.x-discriminator-value}}{{mappingName}}{{/vendorExtensions.x-discriminator-value}}{{#vendorExtensions.x-discriminator-value}}{{{vendorExtensions.x-discriminator-value}}}{{/vendorExtensions.x-discriminator-value}}"), | ||
| {{/discriminator.mappedModels}} | ||
| }){{/jackson}} | ||
| {{#vendorExtensions.x-deduction-model-names}} | ||
| @JsonSubTypes.Type(value = {{.}}.class, name = "{{.}}"), | ||
| {{/vendorExtensions.x-deduction-model-names}} | ||
| }){{/jackson}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI. Since this changes the default codegen, it will take a lot more time to review.