Skip to content
Open
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
2 changes: 2 additions & 0 deletions docs/generators/groovy.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
|groupByResponseContentType| Group server or client methods by response content types. For example, when openapi operation produces one of "application/json" and "application/xml" content types will be generated only one method for both content types. Otherwise for each content type will be generated different method. **Available only for generatos with supportsDividingOperationsByContentType** | |true|
|groupByRequestAndResponseContentType| Group server or client methods by request body and response content types. For example, when openapi operation consumes "application/json" and "application/xml" content type and also api response has content with the same content types, 2 different methods will be generated. The content of the request and response types will match. Otherwise, will be generated 4 methods - for each combination of request body content type and response content type. **Available only for generatos with supportsDividingOperationsByContentType** | |true|

## SUPPORTED VENDOR EXTENSIONS

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,4 +366,5 @@ public interface CodegenConfig {

Set<String> getOpenapiGeneratorIgnoreList();

boolean supportsDividingOperationsByContentType();
}
Original file line number Diff line number Diff line change
Expand Up @@ -454,4 +454,17 @@ public static enum ENUM_PROPERTY_NAMING_TYPE {camelCase, PascalCase, snake_case,
public static final String WAIT_TIME_OF_THREAD = "waitTimeMillis";

public static final String USE_DEFAULT_VALUES_FOR_REQUIRED_VARS = "useDefaultValuesForRequiredVars";

public static final String GROUP_BY_RESPONSE_CONTENT_TYPE = "groupByResponseContentType";
public static final String GROUP_BY_RESPONSE_CONTENT_TYPE_DESC =
"Group server or client methods by response content types. "
+ "For example, when openapi operation produces one of \"application/json\" and \"application/xml\" content types "
+ "will be generated only one method for both content types. Otherwise for each content type will be generated different method.";

public static final String GROUP_BY_REQUEST_AND_RESPONSE_CONTENT_TYPE = "groupByRequestAndResponseContentType";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add a unit test (or sample config) for the two new options groupByResponseContentType and groupByRequestAndResponseContentType?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

public static final String GROUP_BY_REQUEST_AND_RESPONSE_CONTENT_TYPE_DESC =
"Group server or client methods by request body and response content types. "
+ "For example, when openapi operation consumes \"application/json\" and \"application/xml\" content type and also api response "
+ "has content with the same content types, 2 different methods will be generated. The content of the request and response types will match. "
+ "Otherwise, will be generated 4 methods - for each combination of request body content type and response content type.";
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -606,10 +606,10 @@ private void generateModelsForVariable(List<File> files, List<ModelMap> allModel
if (!processedModels.contains(key) && allSchemas.containsKey(key)) {
generateModels(files, allModels, unusedModels, aliasModels, processedModels, () -> Set.of(key));
} else {
LOGGER.info("Type " + variable.getComplexType() + " of variable " + variable.getName() + " could not be resolve because it is not declared as a model.");
LOGGER.info("Type {} of variable {} could not be resolve because it is not declared as a model.", variable.getComplexType(), variable.getName());
}
} else {
LOGGER.info("Type " + variable.getOpenApiType() + " of variable " + variable.getName() + " could not be resolve because it is not declared as a model.");
LOGGER.info("Type {} of variable {} could not be resolve because it is not declared as a model.", variable.getComplexType(), variable.getName());
}
}

Expand Down Expand Up @@ -1002,7 +1002,7 @@ private void generateOpenapiGeneratorIgnoreFile() {
File ignoreFile = new File(ignoreFileNameTarget);
// use the entries provided by the users to pre-populate .openapi-generator-ignore
try {
LOGGER.info("Writing file " + ignoreFileNameTarget + " (which is always overwritten when the option `openapiGeneratorIgnoreFile` is enabled.)");
LOGGER.info("Writing file {} (which is always overwritten when the option `openapiGeneratorIgnoreFile` is enabled.)", ignoreFileNameTarget);
new File(config.outputFolder()).mkdirs();
if (!ignoreFile.createNewFile()) {
// file may already exist, do nothing
Expand Down Expand Up @@ -1465,6 +1465,9 @@ public Map<String, List<CodegenOperation>> processPaths(Paths paths) {
if (paths == null) {
return ops;
}

var divideOperationsByContentType = config.supportsDividingOperationsByContentType();

for (Map.Entry<String, PathItem> pathsEntry : paths.entrySet()) {
String resourcePath = pathsEntry.getKey();
PathItem path = pathsEntry.getValue();
Expand All @@ -1476,11 +1479,35 @@ public Map<String, List<CodegenOperation>> processPaths(Paths paths) {
processOperation(resourcePath, "patch", path.getPatch(), ops, path);
processOperation(resourcePath, "options", path.getOptions(), ops, path);
processOperation(resourcePath, "trace", path.getTrace(), ops, path);

if (divideOperationsByContentType) {
processAdditionalOperations(resourcePath, "x-get", "get", ops, path);
processAdditionalOperations(resourcePath, "x-head", "head", ops, path);
processAdditionalOperations(resourcePath, "x-put", "put", ops, path);
processAdditionalOperations(resourcePath, "x-post", "post", ops, path);
processAdditionalOperations(resourcePath, "x-delete", "delete", ops, path);
processAdditionalOperations(resourcePath, "x-patch", "patch", ops, path);
processAdditionalOperations(resourcePath, "x-options", "options", ops, path);
processAdditionalOperations(resourcePath, "x-trace", "trace", ops, path);
}
}
return ops;
}

public Map<String, List<CodegenOperation>> processWebhooks(Map<String, PathItem> webhooks) {
protected void processAdditionalOperations(String resourcePath, String extName, String httpMethod, Map<String, List<CodegenOperation>> ops, PathItem path) {
if (path.getExtensions() == null || !path.getExtensions().containsKey(extName)) {
return;
}
var xOps = (List<Operation>) path.getExtensions().get(extName);
if (xOps == null) {
return;
}
for (Operation op : xOps) {
processOperation(resourcePath, httpMethod, op, ops, path);
}
}

public Map<String, List<CodegenOperation>> processWebhooks(Map<String, PathItem> webhooks) {
Map<String, List<CodegenOperation>> ops = new TreeMap<>();
// when input file is not valid and doesn't contain any paths
if (webhooks == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2430,4 +2430,9 @@ public void setEnumPropertyNaming(final String enumPropertyNamingType) {
throw new RuntimeException(sb.toString());
}
}

@Override
public boolean supportsDividingOperationsByContentType() {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.*;
import org.openapitools.codegen.config.GlobalSettings;
import org.openapitools.codegen.model.ModelMap;
import org.openapitools.codegen.model.ModelsMap;
import org.openapitools.codegen.templating.mustache.EscapeChar;
Expand Down Expand Up @@ -1157,4 +1158,9 @@ protected void doDataTypeAssignment(final String returnType, DataTypeAssigner da
}
}
}

@Override
public boolean supportsDividingOperationsByContentType() {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1002,7 +1002,7 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation

// add Pageable import only if x-spring-paginated explicitly used
// this allows to use a custom Pageable schema without importing Spring Pageable.
if (Boolean.TRUE.equals(operation.getExtensions().get("x-spring-paginated"))) {
if (operation.getExtensions() != null && Boolean.TRUE.equals(operation.getExtensions().get("x-spring-paginated"))) {
importMapping.put("Pageable", "org.springframework.data.domain.Pageable");
}

Expand Down Expand Up @@ -1082,7 +1082,7 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation

private Set<String> reformatProvideArgsParams(Operation operation) {
Set<String> provideArgsClassSet = new HashSet<>();
Object argObj = operation.getExtensions().get("x-spring-provide-args");
Object argObj = operation.getExtensions() != null ? operation.getExtensions().get("x-spring-provide-args") : null;
if (argObj instanceof List) {
List<String> provideArgs = (List<String>) argObj;
if (!provideArgs.isEmpty()) {
Expand Down Expand Up @@ -1111,7 +1111,7 @@ private Set<String> reformatProvideArgsParams(Operation operation) {
formattedArgs.add(newArg);
}
}
operation.getExtensions().put("x-spring-provide-args", formattedArgs);
operation.addExtension("x-spring-provide-args", formattedArgs);
}
}
return provideArgsClassSet;
Expand Down
Loading