diff --git a/README.md b/README.md index b44d08085e1..851e33300aa 100644 --- a/README.md +++ b/README.md @@ -455,6 +455,7 @@ NAME SYNOPSIS openapi-generator-cli generate [(-a | --auth )] + [--api-name-suffix ] [--api-package ] [--artifact-id ] [--artifact-version ] [(-c | --config )] diff --git a/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/Generate.java b/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/Generate.java index 16d8125b46c..99080ba9c08 100644 --- a/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/Generate.java +++ b/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/Generate.java @@ -65,7 +65,7 @@ public class Generate implements Runnable { private String templateDir; @Option(name = {"-e", "--engine"}, title = "templating engine", - description = "templating engine: \"mustache\" (default) or \"handlebars\" (beta)") + description = "templating engine: \"mustache\" (default) or \"handlebars\" (beta)") private String templatingEngine; @Option( @@ -109,6 +109,10 @@ public class Generate implements Runnable { description = CodegenConstants.MODEL_PACKAGE_DESC) private String modelPackage; + @Option(name = {"--api-name-suffix"}, title = "api name suffix", + description = CodegenConstants.API_NAME_SUFFIX_DESC) + private String apiNameSuffix; + @Option(name = {"--model-name-prefix"}, title = "model name prefix", description = CodegenConstants.MODEL_NAME_PREFIX_DESC) private String modelNamePrefix; @@ -319,6 +323,10 @@ public class Generate implements Runnable { configurator.setModelPackage(modelPackage); } + if (isNotEmpty(apiNameSuffix)) { + configurator.setApiNameSuffix(apiNameSuffix); + } + if (isNotEmpty(modelNamePrefix)) { configurator.setModelNamePrefix(modelNamePrefix); } diff --git a/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/config/GeneratorSettings.java b/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/config/GeneratorSettings.java index 099df0a5fd3..e0772f8aeae 100644 --- a/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/config/GeneratorSettings.java +++ b/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/config/GeneratorSettings.java @@ -40,6 +40,7 @@ public final class GeneratorSettings implements Serializable { private String modelPackage; private String invokerPackage; private String packageName; + private String apiNameSuffix; private String modelNamePrefix; private String modelNameSuffix; private String groupId; @@ -106,6 +107,21 @@ public final class GeneratorSettings implements Serializable { return packageName; } + /** + * Gets a api name suffix for generated models. This name will be appended to a api name. + *

+ * This option is often used to circumvent compilation issues where models match keywords. + *

+ * Example: + *

+ * Suffix Gen applied to Object results in a generated class named ObjectGen. + * + * @return the model name suffix + */ + public String getApiNameSuffix() { + return apiNameSuffix; + } + /** * Gets a model name prefix for generated models. This name will be prefixed to a model name. *

@@ -325,6 +341,7 @@ public final class GeneratorSettings implements Serializable { modelPackage = builder.modelPackage; invokerPackage = builder.invokerPackage; packageName = builder.packageName; + apiNameSuffix = builder.apiNameSuffix; modelNamePrefix = builder.modelNamePrefix; modelNameSuffix = builder.modelNameSuffix; groupId = builder.groupId; @@ -366,6 +383,9 @@ public final class GeneratorSettings implements Serializable { if (isNotEmpty(artifactVersion)) { additional.put("artifactVersion", artifactVersion); } + if (isNotEmpty(apiNameSuffix)) { + additional.put("apiNameSuffix", apiNameSuffix); + } if (isNotEmpty(modelNamePrefix)) { additional.put("modelNamePrefix", modelNamePrefix); } @@ -433,6 +453,7 @@ public final class GeneratorSettings implements Serializable { builder.modelPackage = copy.getModelPackage(); builder.invokerPackage = copy.getInvokerPackage(); builder.packageName = copy.getPackageName(); + builder.apiNameSuffix = copy.getApiNameSuffix(); builder.modelNamePrefix = copy.getModelNamePrefix(); builder.modelNameSuffix = copy.getModelNameSuffix(); builder.groupId = copy.getGroupId(); @@ -479,6 +500,7 @@ public final class GeneratorSettings implements Serializable { private String modelPackage; private String invokerPackage; private String packageName; + private String apiNameSuffix; private String modelNamePrefix; private String modelNameSuffix; private String groupId; @@ -571,6 +593,17 @@ public final class GeneratorSettings implements Serializable { return this; } + /** + * Sets the {@code apiNameSuffix} and returns a reference to this Builder so that the methods can be chained together. + * + * @param apiNameSuffix the {@code apiNameSuffix} to set + * @return a reference to this Builder + */ + public Builder withApiNameSuffix(String apiNameSuffix) { + this.apiNameSuffix = apiNameSuffix; + return this; + } + /** * Sets the {@code modelNamePrefix} and returns a reference to this Builder so that the methods can be chained together. * @@ -880,6 +913,7 @@ public final class GeneratorSettings implements Serializable { ", modelPackage='" + modelPackage + '\'' + ", invokerPackage='" + invokerPackage + '\'' + ", packageName='" + packageName + '\'' + + ", apiNameSuffix='" + apiNameSuffix + '\'' + ", modelNamePrefix='" + modelNamePrefix + '\'' + ", modelNameSuffix='" + modelNameSuffix + '\'' + ", groupId='" + groupId + '\'' + @@ -910,6 +944,7 @@ public final class GeneratorSettings implements Serializable { Objects.equals(getModelPackage(), that.getModelPackage()) && Objects.equals(getInvokerPackage(), that.getInvokerPackage()) && Objects.equals(getPackageName(), that.getPackageName()) && + Objects.equals(getApiNameSuffix(), that.getApiNameSuffix()) && Objects.equals(getModelNamePrefix(), that.getModelNamePrefix()) && Objects.equals(getModelNameSuffix(), that.getModelNameSuffix()) && Objects.equals(getGroupId(), that.getGroupId()) && @@ -937,6 +972,7 @@ public final class GeneratorSettings implements Serializable { getModelPackage(), getInvokerPackage(), getPackageName(), + getApiNameSuffix(), getModelNamePrefix(), getModelNameSuffix(), getGroupId(), diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenConstants.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenConstants.java index ef235748f26..80a708ecd5e 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenConstants.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenConstants.java @@ -206,6 +206,9 @@ public class CodegenConstants { // Codegen constants should define a description and provide proper input validation for the value of serializationLibrary public static final String SERIALIZATION_LIBRARY = "serializationLibrary"; + public static final String API_NAME_SUFFIX = "apiNameSuffix"; + public static final String API_NAME_SUFFIX_DESC = "Suffix that will be appended to all api names."; + public static final String MODEL_NAME_PREFIX = "modelNamePrefix"; public static final String MODEL_NAME_PREFIX_DESC = "Prefix that will be prepended to all model names."; diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index e78bb544175..9a410941b01 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -85,6 +85,7 @@ public class DefaultCodegen implements CodegenConfig { protected Map importMapping = new HashMap(); protected String modelPackage = "", apiPackage = "", fileSuffix; protected String modelNamePrefix = "", modelNameSuffix = ""; + protected String apiNameSuffix = "Api"; protected String testPackage = ""; protected Map apiTemplateFiles = new HashMap(); protected Map modelTemplateFiles = new HashMap(); @@ -180,6 +181,10 @@ public class DefaultCodegen implements CodegenConfig { .get(CodegenConstants.ALLOW_UNICODE_IDENTIFIERS).toString())); } + if (additionalProperties.containsKey(CodegenConstants.API_NAME_SUFFIX)) { + this.setApiNameSuffix((String) additionalProperties.get(CodegenConstants.API_NAME_SUFFIX)); + } + if (additionalProperties.containsKey(CodegenConstants.MODEL_NAME_PREFIX)) { this.setModelNamePrefix((String) additionalProperties.get(CodegenConstants.MODEL_NAME_PREFIX)); } @@ -779,6 +784,14 @@ public class DefaultCodegen implements CodegenConfig { this.modelNameSuffix = modelNameSuffix; } + public String getApiNameSuffix() { + return apiNameSuffix; + } + + public void setApiNameSuffix(String apiNameSuffix) { + this.apiNameSuffix = apiNameSuffix; + } + public void setApiPackage(String apiPackage) { this.apiPackage = apiPackage; } @@ -1692,17 +1705,17 @@ public class DefaultCodegen implements CodegenConfig { } /** - * Output the API (class) name (capitalized) ending with "Api" + * Output the API (class) name (capitalized) ending with the specified or default suffix * Return DefaultApi if name is empty * * @param name the name of the Api - * @return capitalized Api name ending with "Api" + * @return capitalized Api name */ public String toApiName(String name) { if (name.length() == 0) { return "DefaultApi"; } - return camelize(name) + "Api"; + return camelize(name + "_" + apiNameSuffix); } /** diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfigurator.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfigurator.java index c2df323731b..95ac8966391 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfigurator.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfigurator.java @@ -287,6 +287,11 @@ public class CodegenConfigurator { return this; } + public CodegenConfigurator setApiNameSuffix(String suffix) { + generatorSettingsBuilder.withApiNameSuffix(suffix); + return this; + } + public CodegenConfigurator setModelNamePrefix(String prefix) { generatorSettingsBuilder.withModelNamePrefix(prefix); return this; diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractCppCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractCppCodegen.java index c7ca1bc9c1b..5eb052d1a54 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractCppCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractCppCodegen.java @@ -151,7 +151,7 @@ abstract public class AbstractCppCodegen extends DefaultCodegen implements Codeg @Override public String toApiName(String type) { - return sanitizeName(modelNamePrefix + Character.toUpperCase(type.charAt(0)) + type.substring(1) + "Api"); + return sanitizeName(modelNamePrefix + super.toApiName(type)); } @Override diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaJAXRSServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaJAXRSServerCodegen.java index f7c08659665..4b2d39877d3 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaJAXRSServerCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaJAXRSServerCodegen.java @@ -244,11 +244,10 @@ public abstract class AbstractJavaJAXRSServerCodegen extends AbstractJavaCodegen @Override public String toApiName(final String name) { String computed = name; - if (computed.length() == 0) { - return "DefaultApi"; + if (computed.length() > 0) { + computed = sanitizeName(computed); } - computed = sanitizeName(computed); - return camelize(computed) + "Api"; + return super.toApiName(computed); } @Override diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java index 0df25cfd159..6c0c0c13454 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java @@ -531,7 +531,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig name = name.replaceAll("-", "_"); // e.g. PhoneNumberApi.py => phone_number_api.py - return underscore(name) + "_api"; + return underscore(name+ "_" + apiNameSuffix); } @Override @@ -541,11 +541,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig @Override public String toApiName(String name) { - if (name.length() == 0) { - return "DefaultApi"; - } - // e.g. phone_number_api => PhoneNumberApi - return camelize(name) + "Api"; + return super.toApiName(name); } @Override @@ -553,7 +549,7 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig if (name.length() == 0) { return "default_api"; } - return underscore(name) + "_api"; + return underscore(name+ "_" + apiNameSuffix); } @Override diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RubyClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RubyClientCodegen.java index fc23117e458..33d2007a3b2 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RubyClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RubyClientCodegen.java @@ -387,7 +387,7 @@ public class RubyClientCodegen extends AbstractRubyCodegen { name = name.replaceAll("-", "_"); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'. // e.g. PhoneNumberApi.rb => phone_number_api.rb - return underscore(name) + "_api"; + return underscore(name + "_" + apiNameSuffix); } @Override @@ -407,11 +407,7 @@ public class RubyClientCodegen extends AbstractRubyCodegen { @Override public String toApiName(String name) { - if (name.length() == 0) { - return "DefaultApi"; - } - // e.g. phone_number_api => PhoneNumberApi - return camelize(name) + "Api"; + return super.toApiName(name); } @Override diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java index 26ae76afc1b..8c00cbc2811 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java @@ -43,6 +43,7 @@ import org.openapitools.codegen.utils.ModelUtils; import org.testng.Assert; import org.testng.annotations.Test; +import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; @@ -968,4 +969,19 @@ public class DefaultCodegenTest { assertTrue(lambdas.get("indented_16") instanceof IndentedLambda, "Expecting IndentedLambda class"); } + @Test + public void convertApiNameWithEmptySuffix() { + DefaultCodegen codegen = new DefaultCodegen(); + assertEquals(codegen.toApiName("Fake"), "FakeApi"); + assertEquals(codegen.toApiName(""), "DefaultApi"); + } + + @Test + public void convertApiNameWithSuffix() { + DefaultCodegen codegen = new DefaultCodegen(); + codegen.setApiNameSuffix("Test"); + assertEquals(codegen.toApiName("Fake"), "FakeTest"); + assertEquals(codegen.toApiName(""), "DefaultApi"); + } + } diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/config/CodegenConfiguratorTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/config/CodegenConfiguratorTest.java index a53037e0f8f..fe48dff5370 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/config/CodegenConfiguratorTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/config/CodegenConfiguratorTest.java @@ -77,6 +77,7 @@ public class CodegenConfiguratorTest { .setGitHost("test.com") .setGroupId("group") .setHttpUserAgent("agent") + .setApiNameSuffix("api-suffix") .setModelNamePrefix("model-prefix") .setModelNameSuffix("model-suffix") .setModelPackage("model-package") @@ -100,6 +101,7 @@ public class CodegenConfiguratorTest { want(props, CodegenConstants.PREPEND_FORM_OR_BODY_PARAMETERS, false); want(props, CodegenConstants.ENSURE_UNIQUE_PARAMS, true); want(props, CodegenConstants.ALLOW_UNICODE_IDENTIFIERS, true); + want(props, CodegenConstants.API_NAME_SUFFIX, "api-suffix"); want(props, CodegenConstants.MODEL_NAME_PREFIX, "model-prefix"); want(props, CodegenConstants.MODEL_NAME_SUFFIX, "model-suffix"); want(props, CodegenConstants.REMOVE_OPERATION_ID_PREFIX, false);