Skip to content

Commit d0bdd79

Browse files
refactor: unify handling of content examples parsing
1 parent 32e5f0b commit d0bdd79

8 files changed

Lines changed: 71 additions & 78 deletions

File tree

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,7 @@ public static enum ENUM_PROPERTY_NAMING_TYPE {camelCase, PascalCase, snake_case,
481481
public static final String ENUM_DESCRIPTION = "enumDescription";
482482

483483
// Vendor extensions
484+
public static final String X_EXAMPLE = "x-example";
484485
public static final String X_INTERNAL = "x-internal";
485486
public static final String X_PARENT = "x-parent";
486487
public static final String X_COMPOSED_DATA_TYPE = "x-composed-data-type";

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

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2115,8 +2115,8 @@ public void setParameterExampleValue(CodegenParameter codegenParameter) {
21152115
// set the example value
21162116
// if not specified in x-example, generate a default value
21172117
// TODO need to revise how to obtain the example value
2118-
if (codegenParameter.vendorExtensions != null && codegenParameter.vendorExtensions.containsKey("x-example")) {
2119-
codegenParameter.example = Json.pretty(codegenParameter.vendorExtensions.get("x-example"));
2118+
if (codegenParameter.vendorExtensions != null && codegenParameter.vendorExtensions.containsKey(X_EXAMPLE)) {
2119+
codegenParameter.example = Json.pretty(codegenParameter.vendorExtensions.get(X_EXAMPLE));
21202120
} else if (codegenParameter.isBoolean) {
21212121
codegenParameter.example = "true";
21222122
} else if (codegenParameter.isLong) {
@@ -2201,25 +2201,13 @@ public void setParameterExamples(CodegenParameter codegenParameter, Parameter pa
22012201
public void setParameterExampleValue(CodegenParameter codegenParameter, RequestBody requestBody) {
22022202
Content content = requestBody.getContent();
22032203

2204-
if (content.size() > 1) {
2205-
// @see ModelUtils.getSchemaFromContent()
2206-
once(LOGGER).debug("Multiple MediaTypes found, using only the first one");
2207-
}
2204+
Optional<Object> contentExample = ExamplesUtils.getContentExample(content);
22082205

2209-
MediaType mediaType = content.values().iterator().next();
2210-
if (mediaType.getExample() != null) {
2211-
codegenParameter.example = mediaType.getExample().toString();
2206+
if (contentExample.isPresent()) {
2207+
codegenParameter.example = contentExample.toString();
22122208
return;
22132209
}
22142210

2215-
if (mediaType.getExamples() != null && !mediaType.getExamples().isEmpty()) {
2216-
Example example = mediaType.getExamples().values().iterator().next();
2217-
if (example.getValue() != null) {
2218-
codegenParameter.example = example.getValue().toString();
2219-
return;
2220-
}
2221-
}
2222-
22232211
setParameterExampleValue(codegenParameter);
22242212
}
22252213

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939

4040
import static org.openapitools.codegen.CodegenConstants.ENUM_VARS;
4141
import static org.openapitools.codegen.CodegenConstants.X_ENUM_BYTE;
42+
import static org.openapitools.codegen.CodegenConstants.X_EXAMPLE;
4243
import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER;
4344
import static org.openapitools.codegen.utils.EnumUtils.getEnumVarsAsString;
4445
import static org.openapitools.codegen.utils.StringUtils.camelize;
@@ -1006,8 +1007,8 @@ public void setParameterExampleValue(CodegenParameter codegenParameter) {
10061007
// set the example value
10071008
// if not specified in x-example, generate a default value
10081009
// TODO need to revise how to obtain the example value
1009-
if (codegenParameter.vendorExtensions != null && codegenParameter.vendorExtensions.containsKey("x-example")) {
1010-
codegenParameter.example = Json.pretty(codegenParameter.vendorExtensions.get("x-example"));
1010+
if (codegenParameter.vendorExtensions != null && codegenParameter.vendorExtensions.containsKey(X_EXAMPLE)) {
1011+
codegenParameter.example = Json.pretty(codegenParameter.vendorExtensions.get(X_EXAMPLE));
10111012
} else if (Boolean.TRUE.equals(codegenParameter.isBoolean)) {
10121013
codegenParameter.example = "true";
10131014
} else if (Boolean.TRUE.equals(codegenParameter.isLong)) {

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

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import io.swagger.v3.oas.models.Operation;
3131
import io.swagger.v3.oas.models.PathItem;
3232
import io.swagger.v3.oas.models.examples.Example;
33-
import io.swagger.v3.oas.models.media.Content;
3433
import io.swagger.v3.oas.models.media.MediaType;
3534
import io.swagger.v3.oas.models.media.Schema;
3635
import io.swagger.v3.oas.models.media.StringSchema;
@@ -1764,36 +1763,16 @@ public void setParameterExampleValue(CodegenParameter codegenParameter, Paramete
17641763
public void setParameterExampleValue(CodegenParameter codegenParameter, RequestBody requestBody) {
17651764
boolean isModel = (codegenParameter.isModel || (codegenParameter.isContainer && codegenParameter.getItems().isModel));
17661765

1767-
Content content = requestBody.getContent();
1768-
1769-
if (content.size() > 1) {
1770-
// @see ModelUtils.getSchemaFromContent()
1771-
LOGGER.debug("Multiple MediaTypes found, using only the first one");
1772-
}
1773-
1774-
MediaType mediaType = content.values().iterator().next();
1775-
if (mediaType.getExample() != null) {
1776-
if (isModel) {
1766+
MediaType mediaType = requestBody.getContent().values().iterator().next();
1767+
boolean hasExample = mediaType.getExample() != null || (mediaType.getExamples() != null && !mediaType.getExamples().isEmpty());
1768+
if (isModel) {
1769+
if (hasExample) {
17771770
once(LOGGER).warn("Ignoring complex example on request body");
1778-
} else {
1779-
codegenParameter.example = mediaType.getExample().toString();
1780-
return;
1781-
}
1782-
}
1783-
1784-
if (mediaType.getExamples() != null && !mediaType.getExamples().isEmpty()) {
1785-
Example example = mediaType.getExamples().values().iterator().next();
1786-
if (example.getValue() != null) {
1787-
if (isModel) {
1788-
once(LOGGER).warn("Ignoring complex example on request body");
1789-
} else {
1790-
codegenParameter.example = example.getValue().toString();
1791-
return;
1792-
}
17931771
}
1772+
setParameterExampleValue(codegenParameter);
1773+
} else {
1774+
super.setParameterExampleValue(codegenParameter, requestBody);
17941775
}
1795-
1796-
setParameterExampleValue(codegenParameter);
17971776
}
17981777

17991778
@Override

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,8 +1087,8 @@ public CodegenParameter fromRequestBody(RequestBody body, Set<String> imports, S
10871087
codegenParameter.isByteArray = ModelUtils.isByteArraySchema(original_schema);
10881088

10891089
// This is a model, so should only have an example if explicitly defined.
1090-
if (codegenParameter.vendorExtensions != null && codegenParameter.vendorExtensions.containsKey("x-example")) {
1091-
codegenParameter.example = Json.pretty(codegenParameter.vendorExtensions.get("x-example"));
1090+
if (codegenParameter.vendorExtensions != null && codegenParameter.vendorExtensions.containsKey(X_EXAMPLE)) {
1091+
codegenParameter.example = Json.pretty(codegenParameter.vendorExtensions.get(X_EXAMPLE));
10921092
} else if (!codegenParameter.required) {
10931093
//mandatory parameter use the example in the yaml. if no example, it is also null.
10941094
codegenParameter.example = null;
@@ -1784,24 +1784,24 @@ private void processParam(CodegenParameter param, CodegenOperation op) {
17841784

17851785
if (param.required) {
17861786
if (example != null) {
1787-
param.vendorExtensions.put("x-example", example);
1787+
param.vendorExtensions.put(X_EXAMPLE, example);
17881788
} else if (param.isArray) {
17891789
// Use the empty list if we don't have an example
1790-
param.vendorExtensions.put("x-example", "&Vec::new()");
1790+
param.vendorExtensions.put(X_EXAMPLE, "&Vec::new()");
17911791
} else {
17921792
// If we don't have an example that we can provide, we need to disable the client example, as it won't build.
1793-
param.vendorExtensions.put("x-example", "???");
1793+
param.vendorExtensions.put(X_EXAMPLE, "???");
17941794
op.vendorExtensions.put("x-no-client-example", Boolean.TRUE);
17951795
}
17961796
} else if ((param.dataFormat != null) && (("date-time".equals(param.dataFormat)) || ("date".equals(param.dataFormat)))) {
17971797
param.vendorExtensions.put("x-format-string", "{:?}");
1798-
param.vendorExtensions.put("x-example", "None");
1798+
param.vendorExtensions.put(X_EXAMPLE, "None");
17991799
} else {
18001800
// Not required, so override the format string and example
18011801
boolean itemsAreEnum = param.isArray && param.items != null && param.items.getIsEnumOrRef();
18021802
param.vendorExtensions.put("x-format-string", (param.getIsEnumOrRef() || itemsAreEnum) ? "{}" : "{:?}");
18031803
String exampleString = (example != null) ? "Some(" + example + ")" : "None";
1804-
param.vendorExtensions.put("x-example", exampleString);
1804+
param.vendorExtensions.put(X_EXAMPLE, exampleString);
18051805
}
18061806

18071807
// Add a vendor extension to flag if this can have validate() run on it.

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@
4848
import java.util.regex.Pattern;
4949
import java.util.stream.Collectors;
5050

51-
import static org.openapitools.codegen.CodegenConstants.ENUM_VALUES;
5251
import static org.openapitools.codegen.CodegenConstants.X_ONE_OF_NAME;
52+
import static org.openapitools.codegen.CodegenConstants.X_EXAMPLE;
5353
import static org.openapitools.codegen.utils.EnumUtils.getEnumValues;
5454
import static org.openapitools.codegen.utils.EnumUtils.hasEnumValues;
5555
import static org.openapitools.codegen.utils.StringUtils.camelize;
@@ -1028,8 +1028,8 @@ public CodegenParameter fromRequestBody(RequestBody body, Set<String> imports, S
10281028

10291029
// This is a model, so should only have an example if explicitly
10301030
// defined.
1031-
if (codegenParameter.vendorExtensions != null && codegenParameter.vendorExtensions.containsKey("x-example")) {
1032-
codegenParameter.example = Json.pretty(codegenParameter.vendorExtensions.get("x-example"));
1031+
if (codegenParameter.vendorExtensions != null && codegenParameter.vendorExtensions.containsKey(X_EXAMPLE)) {
1032+
codegenParameter.example = Json.pretty(codegenParameter.vendorExtensions.get(X_EXAMPLE));
10331033
} else if (!codegenParameter.required) {
10341034
//mandatory parameter use the example in the yaml. if no example, it is also null.
10351035
codegenParameter.example = null;
@@ -1583,23 +1583,23 @@ private void processParam(CodegenParameter param, CodegenOperation op) {
15831583

15841584
if (param.required) {
15851585
if (example != null) {
1586-
param.vendorExtensions.put("x-example", example);
1586+
param.vendorExtensions.put(X_EXAMPLE, example);
15871587
} else if (param.isArray) {
15881588
// Use the empty list if we don't have an example
1589-
param.vendorExtensions.put("x-example", "&Vec::new()");
1589+
param.vendorExtensions.put(X_EXAMPLE, "&Vec::new()");
15901590
} else {
15911591
// If we don't have an example that we can provide, we need to disable the client example, as it won't build.
1592-
param.vendorExtensions.put("x-example", "???");
1592+
param.vendorExtensions.put(X_EXAMPLE, "???");
15931593
op.vendorExtensions.put("x-no-client-example", Boolean.TRUE);
15941594
}
15951595
} else if ((param.dataFormat != null) && (("date-time".equals(param.dataFormat)) || ("date".equals(param.dataFormat)))) {
15961596
param.vendorExtensions.put("x-format-string", "{:?}");
1597-
param.vendorExtensions.put("x-example", "None");
1597+
param.vendorExtensions.put(X_EXAMPLE, "None");
15981598
} else {
15991599
// Not required, so override the format string and example
16001600
param.vendorExtensions.put("x-format-string", "{:?}");
16011601
String exampleString = (example != null) ? "Some(" + example + ")" : "None";
1602-
param.vendorExtensions.put("x-example", exampleString);
1602+
param.vendorExtensions.put(X_EXAMPLE, exampleString);
16031603
}
16041604
}
16051605

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

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import org.openapitools.codegen.model.ModelsMap;
4040
import org.openapitools.codegen.model.OperationMap;
4141
import org.openapitools.codegen.model.OperationsMap;
42+
import org.openapitools.codegen.utils.ExamplesUtils;
4243
import org.openapitools.codegen.utils.ModelUtils;
4344
import org.slf4j.Logger;
4445
import org.slf4j.LoggerFactory;
@@ -51,6 +52,7 @@
5152
import java.util.regex.Matcher;
5253
import java.util.regex.Pattern;
5354

55+
import static org.openapitools.codegen.CodegenConstants.X_EXAMPLE;
5456
import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER;
5557
import static org.openapitools.codegen.utils.OnceLogger.once;
5658
import static org.openapitools.codegen.utils.StringUtils.camelize;
@@ -1060,8 +1062,8 @@ public void setParameterExampleValue(CodegenParameter codegenParameter, Paramete
10601062
}
10611063

10621064
Object example = null;
1063-
if (codegenParameter.vendorExtensions != null && codegenParameter.vendorExtensions.containsKey("x-example")) {
1064-
example = codegenParameter.vendorExtensions.get("x-example");
1065+
if (codegenParameter.vendorExtensions != null && codegenParameter.vendorExtensions.containsKey(X_EXAMPLE)) {
1066+
example = codegenParameter.vendorExtensions.get(X_EXAMPLE);
10651067
} else if (parameter.getExample() != null) {
10661068
example = parameter.getExample();
10671069
} else if (parameter.getExamples() != null && !parameter.getExamples().isEmpty() && parameter.getExamples().values().iterator().next().getValue() != null) {
@@ -1082,16 +1084,13 @@ public void setParameterExampleValue(CodegenParameter codegenParameter, Paramete
10821084
*/
10831085
@Override
10841086
public void setParameterExampleValue(CodegenParameter codegenParameter, RequestBody requestBody) {
1085-
if (codegenParameter.vendorExtensions != null && codegenParameter.vendorExtensions.containsKey("x-example")) {
1086-
codegenParameter.example = Json.pretty(codegenParameter.vendorExtensions.get("x-example"));
1087+
if (codegenParameter.vendorExtensions != null && codegenParameter.vendorExtensions.containsKey(X_EXAMPLE)) {
1088+
codegenParameter.example = Json.pretty(codegenParameter.vendorExtensions.get(X_EXAMPLE));
10871089
}
10881090

10891091
Content content = requestBody.getContent();
10901092

1091-
if (content.size() > 1) {
1092-
// @see ModelUtils.getSchemaFromContent()
1093-
once(LOGGER).debug("Multiple MediaTypes found, using only the first one");
1094-
}
1093+
Optional<Object> contentExample = ExamplesUtils.getContentExample(content);
10951094

10961095
MediaType mediaType = content.values().iterator().next();
10971096
Schema schema = mediaType.getSchema();
@@ -1100,14 +1099,7 @@ public void setParameterExampleValue(CodegenParameter codegenParameter, RequestB
11001099
return;
11011100
}
11021101

1103-
Object example = null;
1104-
if (mediaType.getExample() != null) {
1105-
example = mediaType.getExample();
1106-
} else if (mediaType.getExamples() != null && !mediaType.getExamples().isEmpty() && mediaType.getExamples().values().iterator().next().getValue() != null) {
1107-
example = mediaType.getExamples().values().iterator().next().getValue();
1108-
} else {
1109-
example = getObjectExample(schema);
1110-
}
1102+
Object example = contentExample.orElseGet(() -> getObjectExample(schema));
11111103
example = exampleFromStringOrArraySchema(schema, example, codegenParameter.paramName);
11121104
codegenParameter.example = toExampleValue(schema, example);
11131105
}

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import io.swagger.v3.oas.models.OpenAPI;
66
import io.swagger.v3.oas.models.examples.Example;
77
import io.swagger.v3.oas.models.media.Content;
8+
import io.swagger.v3.oas.models.media.MediaType;
9+
import io.swagger.v3.oas.models.parameters.RequestBody;
810
import io.swagger.v3.oas.models.responses.ApiResponse;
911
import org.slf4j.Logger;
1012
import org.slf4j.LoggerFactory;
@@ -35,6 +37,36 @@ public static Map<String, Example> getExamplesFromResponse(OpenAPI openAPI, ApiR
3537
}
3638
}
3739

40+
/**
41+
* Returns the example object for a request body. Note that the current implementation only fetches the first example
42+
* found. If there are an {@code example} defined, then {@code examples} is not considered.
43+
* <p>
44+
* Only the first media type is considered.
45+
* @see ModelUtils#getSchemaFromRequestBody(RequestBody)
46+
* @see ModelUtils#getSchemaFromResponse(OpenAPI, ApiResponse)
47+
*
48+
* @param content The request body content
49+
* @return The first example found, or an empty optional if no example is found
50+
*/
51+
public static Optional<Object> getContentExample(Content content) {
52+
if (content.size() > 1) {
53+
once(LOGGER).debug("Multiple MediaTypes found, using only the first one");
54+
}
55+
56+
MediaType mediaType = content.values().iterator().next();
57+
if (mediaType.getExample() != null) {
58+
return Optional.of(mediaType.getExample());
59+
}
60+
61+
if (mediaType.getExamples() != null && !mediaType.getExamples().isEmpty()) {
62+
Example example = mediaType.getExamples().values().iterator().next();
63+
if (example.getValue() != null) {
64+
return Optional.of(example.getValue());
65+
}
66+
}
67+
return Optional.empty();
68+
}
69+
3870
private static Map<String, Example> getExamplesFromContent(Content content) {
3971
if (content == null || content.isEmpty())
4072
return Collections.emptyMap();

0 commit comments

Comments
 (0)