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 codegenParameter Codegen parameter
|
||||||
* @param mediaType MediaType from the request body
|
* @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) {
|
if (mediaType != null && mediaType.getEncoding() != null) {
|
||||||
Encoding encoding = mediaType.getEncoding().get(codegenParameter.baseName);
|
Encoding encoding = mediaType.getEncoding().get(codegenParameter.baseName);
|
||||||
if (encoding != null) {
|
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.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 {
|
} else {
|
||||||
LOGGER.debug("encoding not specified for {}", codegenParameter.baseName);
|
LOGGER.debug("encoding not specified for {}", codegenParameter.baseName);
|
||||||
}
|
}
|
||||||
@ -4087,7 +4120,7 @@ public class DefaultCodegen implements CodegenConfig {
|
|||||||
formParams = fromRequestBodyToFormParameters(requestBody, imports);
|
formParams = fromRequestBodyToFormParameters(requestBody, imports);
|
||||||
op.isMultipart = contentType.startsWith("multipart");
|
op.isMultipart = contentType.startsWith("multipart");
|
||||||
for (CodegenParameter cp : formParams) {
|
for (CodegenParameter cp : formParams) {
|
||||||
setParameterContentType(cp, requestBody.getContent().get(contentType));
|
setParameterEncodingValues(cp, requestBody.getContent().get(contentType));
|
||||||
postProcessParameter(cp);
|
postProcessParameter(cp);
|
||||||
}
|
}
|
||||||
// add form parameters to the beginning of all parameter list
|
// 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);
|
LOGGER.warn("Could not compute datatypeWithEnum from {}, {}", arrayInnerProperty.baseType, arrayInnerProperty.enumName);
|
||||||
}
|
}
|
||||||
// end of hoisting
|
// 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);
|
String collectionFormat = getCollectionFormat(codegenParameter);
|
||||||
// default to csv:
|
|
||||||
codegenParameter.collectionFormat = StringUtils.isEmpty(collectionFormat) ? "csv" : collectionFormat;
|
codegenParameter.collectionFormat = StringUtils.isEmpty(collectionFormat) ? "csv" : collectionFormat;
|
||||||
|
codegenParameter.isCollectionFormatMulti = "multi".equals(collectionFormat);
|
||||||
|
|
||||||
// recursively add import
|
// recursively add import
|
||||||
while (arrayInnerProperty != null) {
|
while (arrayInnerProperty != null) {
|
||||||
@ -6444,8 +6478,6 @@ public class DefaultCodegen implements CodegenConfig {
|
|||||||
// set nullable
|
// set nullable
|
||||||
setParameterNullable(codegenParameter, codegenProperty);
|
setParameterNullable(codegenParameter, codegenProperty);
|
||||||
|
|
||||||
//TODO collectionFormat for form parameter not yet supported
|
|
||||||
//codegenParameter.collectionFormat = getCollectionFormat(propertySchema);
|
|
||||||
return codegenParameter;
|
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}.
|
* for the {@link CodegenParameter}.
|
||||||
*
|
*
|
||||||
* @param codegenParameter parameter
|
* @param codegenParameter parameter
|
||||||
* @return string for a collectionFormat.
|
* @return string for a collectionFormat.
|
||||||
*/
|
*/
|
||||||
protected String getCollectionFormat(CodegenParameter codegenParameter) {
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private CodegenComposedSchemas getComposedSchemas(Schema schema) {
|
private CodegenComposedSchemas getComposedSchemas(Schema schema) {
|
||||||
if (!(schema instanceof ComposedSchema) && schema.getNot()==null) {
|
if (!(schema instanceof ComposedSchema) && schema.getNot()==null) {
|
||||||
|
@ -4064,6 +4064,44 @@ public class DefaultCodegenTest {
|
|||||||
cp = mt.getSchema();
|
cp = mt.getSchema();
|
||||||
assertEquals(cp.baseName, "SchemaForRequestBodyTextPlain");
|
assertEquals(cp.baseName, "SchemaForRequestBodyTextPlain");
|
||||||
assertTrue(cp.isString);
|
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
|
@Test
|
||||||
|
@ -98,6 +98,57 @@ paths:
|
|||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: OK
|
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:
|
components:
|
||||||
headers:
|
headers:
|
||||||
X-Rate-Limit:
|
X-Rate-Limit:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user