forked from loafle/openapi-generator-original
Apply style and explode values from encoding for form-encoded request body parameters (#12162)
This commit is contained in:
parent
5578f178d4
commit
c3976a4a4d
@ -1932,16 +1932,49 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the content type of the parameter based on the encoding specified in the request body.
|
||||
* Sets the content type, style, and explode of the parameter based on the encoding specified
|
||||
* in the request body.
|
||||
*
|
||||
* @param codegenParameter Codegen parameter
|
||||
* @param mediaType MediaType from the request body
|
||||
*/
|
||||
public void setParameterContentType(CodegenParameter codegenParameter, MediaType mediaType) {
|
||||
public void setParameterEncodingValues(CodegenParameter codegenParameter, MediaType mediaType) {
|
||||
if (mediaType != null && mediaType.getEncoding() != null) {
|
||||
Encoding encoding = mediaType.getEncoding().get(codegenParameter.baseName);
|
||||
if (encoding != null) {
|
||||
boolean styleGiven = true;
|
||||
Encoding.StyleEnum style = encoding.getStyle();
|
||||
if(style == null || style == Encoding.StyleEnum.FORM) {
|
||||
// (Unfortunately, swagger-parser-v3 will always provide 'form'
|
||||
// when style is not specified, so we can't detect that)
|
||||
style = Encoding.StyleEnum.FORM;
|
||||
styleGiven = false;
|
||||
}
|
||||
boolean explodeGiven = true;
|
||||
Boolean explode = encoding.getExplode();
|
||||
if(explode == null) {
|
||||
explode = style == Encoding.StyleEnum.FORM; // Default to True when form, False otherwise
|
||||
explodeGiven = false;
|
||||
}
|
||||
|
||||
if(!styleGiven && !explodeGiven) {
|
||||
// Ignore contentType if style or explode are specified.
|
||||
codegenParameter.contentType = encoding.getContentType();
|
||||
}
|
||||
|
||||
codegenParameter.style = style.toString();
|
||||
codegenParameter.isDeepObject = Encoding.StyleEnum.DEEP_OBJECT == style;
|
||||
|
||||
if(codegenParameter.isContainer) {
|
||||
codegenParameter.isExplode = explode;
|
||||
String collectionFormat = getCollectionFormat(codegenParameter);
|
||||
codegenParameter.collectionFormat = StringUtils.isEmpty(collectionFormat) ? "csv" : collectionFormat;
|
||||
codegenParameter.isCollectionFormatMulti = "multi".equals(collectionFormat);
|
||||
} else {
|
||||
codegenParameter.isExplode = false;
|
||||
codegenParameter.collectionFormat = null;
|
||||
codegenParameter.isCollectionFormatMulti = false;
|
||||
}
|
||||
} else {
|
||||
LOGGER.debug("encoding not specified for {}", codegenParameter.baseName);
|
||||
}
|
||||
@ -4087,7 +4120,7 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
formParams = fromRequestBodyToFormParameters(requestBody, imports);
|
||||
op.isMultipart = contentType.startsWith("multipart");
|
||||
for (CodegenParameter cp : formParams) {
|
||||
setParameterContentType(cp, requestBody.getContent().get(contentType));
|
||||
setParameterEncodingValues(cp, requestBody.getContent().get(contentType));
|
||||
postProcessParameter(cp);
|
||||
}
|
||||
// add form parameters to the beginning of all parameter list
|
||||
@ -6398,11 +6431,12 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
LOGGER.warn("Could not compute datatypeWithEnum from {}, {}", arrayInnerProperty.baseType, arrayInnerProperty.enumName);
|
||||
}
|
||||
// end of hoisting
|
||||
//TODO fix collectionFormat for form parameters
|
||||
//collectionFormat = getCollectionFormat(s);
|
||||
|
||||
// collectionFormat for form parameter does not consider
|
||||
// style and explode from encoding at this point
|
||||
String collectionFormat = getCollectionFormat(codegenParameter);
|
||||
// default to csv:
|
||||
codegenParameter.collectionFormat = StringUtils.isEmpty(collectionFormat) ? "csv" : collectionFormat;
|
||||
codegenParameter.isCollectionFormatMulti = "multi".equals(collectionFormat);
|
||||
|
||||
// recursively add import
|
||||
while (arrayInnerProperty != null) {
|
||||
@ -6444,8 +6478,6 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
// set nullable
|
||||
setParameterNullable(codegenParameter, codegenProperty);
|
||||
|
||||
//TODO collectionFormat for form parameter not yet supported
|
||||
//codegenParameter.collectionFormat = getCollectionFormat(propertySchema);
|
||||
return codegenParameter;
|
||||
}
|
||||
|
||||
@ -7367,15 +7399,31 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns null by default but can be overwritten to return a valid collectionFormat
|
||||
* Builds OAPI 2.0 collectionFormat value based on style and explode values
|
||||
* for the {@link CodegenParameter}.
|
||||
*
|
||||
* @param codegenParameter parameter
|
||||
* @return string for a collectionFormat.
|
||||
*/
|
||||
protected String getCollectionFormat(CodegenParameter codegenParameter) {
|
||||
if ("form".equals(codegenParameter.style)) {
|
||||
// Ref: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.1.md#style-values
|
||||
if (codegenParameter.isExplode) {
|
||||
return "multi";
|
||||
} else {
|
||||
return "csv";
|
||||
}
|
||||
} else if ("simple".equals(codegenParameter.style)) {
|
||||
return "csv";
|
||||
} else if ("pipeDelimited".equals(codegenParameter.style)) {
|
||||
return "pipes";
|
||||
} else if ("spaceDelimited".equals(codegenParameter.style)) {
|
||||
return "ssv";
|
||||
} else {
|
||||
// Doesn't map to any of the collectionFormat strings
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private CodegenComposedSchemas getComposedSchemas(Schema schema) {
|
||||
if (!(schema instanceof ComposedSchema) && schema.getNot()==null) {
|
||||
|
@ -4064,6 +4064,44 @@ public class DefaultCodegenTest {
|
||||
cp = mt.getSchema();
|
||||
assertEquals(cp.baseName, "SchemaForRequestBodyTextPlain");
|
||||
assertTrue(cp.isString);
|
||||
|
||||
path = "/requestBodyWithEncodingTypes";
|
||||
co = codegen.fromOperation(path, "POST", openAPI.getPaths().get(path).getPost(), null);
|
||||
List<CodegenParameter> formParams = co.formParams;
|
||||
|
||||
assertEquals(formParams.get(0).paramName, "intParam");
|
||||
assertFalse(formParams.get(0).isContainer);
|
||||
assertFalse(formParams.get(0).isExplode); // Should not be true for non-container
|
||||
|
||||
assertEquals(formParams.get(1).paramName, "explodeTrue");
|
||||
assertTrue(formParams.get(1).isContainer);
|
||||
assertEquals(formParams.get(1).style, Encoding.StyleEnum.FORM.toString());
|
||||
assertTrue(formParams.get(1).isExplode);
|
||||
assertNull(formParams.get(1).contentType);
|
||||
|
||||
assertEquals(formParams.get(2).paramName, "explodeFalse");
|
||||
assertTrue(formParams.get(2).isContainer);
|
||||
assertEquals(formParams.get(2).style, Encoding.StyleEnum.FORM.toString());
|
||||
assertFalse(formParams.get(2).isExplode);
|
||||
assertNull(formParams.get(2).contentType);
|
||||
|
||||
assertEquals(formParams.get(3).paramName, "noStyleNoExplode");
|
||||
assertTrue(formParams.get(3).isContainer);
|
||||
assertEquals(formParams.get(3).style, Encoding.StyleEnum.FORM.toString());
|
||||
assertTrue(formParams.get(3).isExplode); // Defaults to true for style == FORM
|
||||
assertEquals(formParams.get(3).contentType, "text/plain");
|
||||
|
||||
assertEquals(formParams.get(4).paramName, "styleSpecified");
|
||||
assertTrue(formParams.get(4).isContainer);
|
||||
assertEquals(formParams.get(4).style, Encoding.StyleEnum.SPACE_DELIMITED.toString());
|
||||
assertFalse(formParams.get(4).isExplode);
|
||||
assertNull(formParams.get(4).contentType);
|
||||
|
||||
assertEquals(formParams.get(5).paramName, "styleSpecifiedNoExplode");
|
||||
assertTrue(formParams.get(5).isContainer);
|
||||
assertEquals(formParams.get(5).style, Encoding.StyleEnum.SPACE_DELIMITED.toString());
|
||||
assertFalse(formParams.get(5).isExplode); // Defaults to false for style other than FORM
|
||||
assertNull(formParams.get(5).contentType);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -98,6 +98,57 @@ paths:
|
||||
responses:
|
||||
200:
|
||||
description: OK
|
||||
/requestBodyWithEncodingTypes:
|
||||
post:
|
||||
requestBody:
|
||||
content:
|
||||
application/x-www-form-urlencoded:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
int-param:
|
||||
type: integer
|
||||
explode-true:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
explode-false:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
no-style-no-explode:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
style-specified:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
style-specified-no-explode:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
encoding:
|
||||
int-param:
|
||||
explode: true # should be disregarded for non-container
|
||||
explode-true:
|
||||
contentType: text/plain # should be disregarded
|
||||
explode: true
|
||||
explode-false:
|
||||
contentType: text/plain # should be disregarded
|
||||
explode: false
|
||||
no-style-no-explode:
|
||||
contentType: text/plain
|
||||
style-specified:
|
||||
contentType: text/plain # should be disregarded
|
||||
style: spaceDelimited
|
||||
explode: false
|
||||
style-specified-no-explode:
|
||||
contentType: text/plain # should be disregarded
|
||||
style: spaceDelimited
|
||||
responses:
|
||||
200:
|
||||
description: OK
|
||||
components:
|
||||
headers:
|
||||
X-Rate-Limit:
|
||||
|
Loading…
x
Reference in New Issue
Block a user