[core] Normalizing vendor extension naming (#5192)

* [core] Normalizing vendor extension naming

According to [OAS 2.0][1] and [OAS 3.0][2] Specifications:

> Allows extensions to the OpenAPI Schema. The field name MUST begin with x-,
>  for example, x-internal-id. The value can be null, a primitive, an array or an object.
>  Can have any valid JSON format value.

This commit attempts to define a [clear identifier design format][3] of
maintaining lower-kebab casing and following the x- prefix defined by
OAI Specification.

Following a convention that matches that used by others (see [autorest][4]), we will remove
any confusion about naming strategies for template authors and
customizers. Following the lower-kebab convention will allow us to
convert from camelCase and missing prefixes to the desired format. For
example, these conversions are simple to make for template consistency:

* customValue => x-custom-value
* x-customValue => x-custom-value
* x-custom-value => x-custom-value

This convention also allows us to define a single standard for use
across all generators. This means no occurrence of x-operationId in one
generator and x-operation-id in another.

[1]: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#patterned-objects
[2]: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#specificationExtensions
[3]: https://tools.ietf.org/html/draft-wilde-registries-01#section-3.4
[4]: https://github.com/Azure/autorest/tree/master/docs/extensions

* Incorporate feedback to avoid race/blocking in OnceLogger

* Remove unnecessary additional log config

* Add tests,comments for OnceLogger

* Test caffeine cache with FakeTicker
This commit is contained in:
Jim Schubert 2020-02-06 09:52:58 -05:00 committed by GitHub
parent 1bba3a563e
commit 8d6286dfae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 978 additions and 230 deletions

View File

@ -53,16 +53,6 @@
<level>ERROR</level> <level>ERROR</level>
</filter> </filter>
</appender> </appender>
<appender name="ONCELOGGER_COLOR" class="ch.qos.logback.core.ConsoleAppender">
<target>System.err</target>
<withJansi>true</withJansi>
<evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator">
<marker>ONCE</marker>
</evaluator>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>[%thread] %highlight(%-5level) %logger{36} - %red(%msg)%n</pattern>
</encoder>
</appender>
<logger name="io.swagger" level="warn"> <logger name="io.swagger" level="warn">
<!-- Colorize by passing -Dcolor --> <!-- Colorize by passing -Dcolor -->

View File

@ -385,11 +385,22 @@
<version>${kotlin-version}</version> <version>${kotlin-version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava-testlib</artifactId>
<version>28.2-jre</version>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>net.java.dev.jna</groupId> <groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId> <artifactId>jna</artifactId>
<version>5.5.0</version> <version>5.5.0</version>
</dependency> </dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>2.8.1</version>
</dependency>
</dependencies> </dependencies>
<repositories> <repositories>
<repository> <repository>

View File

@ -32,6 +32,7 @@ import org.slf4j.LoggerFactory;
import java.util.*; import java.util.*;
import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.camelize; import static org.openapitools.codegen.utils.StringUtils.camelize;
public abstract class AbstractApexCodegen extends DefaultCodegen implements CodegenConfig { public abstract class AbstractApexCodegen extends DefaultCodegen implements CodegenConfig {
@ -455,9 +456,16 @@ public abstract class AbstractApexCodegen extends DefaultCodegen implements Code
} }
} }
cm.vendorExtensions.put("hasPropertyMappings", !propertyMappings.isEmpty()); // TODO: 5.0: Remove this block and ensure templates use the newer property naming.
cm.vendorExtensions.put("hasDefaultValues", hasDefaultValues); once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
cm.vendorExtensions.put("propertyMappings", propertyMappings); cm.vendorExtensions.put("hasPropertyMappings", !propertyMappings.isEmpty()); // TODO: 5.0 Remove
cm.vendorExtensions.put("hasDefaultValues", hasDefaultValues); // TODO: 5.0 Remove
cm.vendorExtensions.put("propertyMappings", propertyMappings); // TODO: 5.0 Remove
cm.vendorExtensions.put("x-has-property-mappings", !propertyMappings.isEmpty());
cm.vendorExtensions.put("x-has-default-values", hasDefaultValues);
cm.vendorExtensions.put("x-property-mappings", propertyMappings);
if (!propertyMappings.isEmpty()) { if (!propertyMappings.isEmpty()) {
cm.interfaces.add("OAS.MappedProperties"); cm.interfaces.add("OAS.MappedProperties");

View File

@ -34,6 +34,7 @@ import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.util.*; import java.util.*;
import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.camelize; import static org.openapitools.codegen.utils.StringUtils.camelize;
public abstract class AbstractCSharpCodegen extends DefaultCodegen implements CodegenConfig { public abstract class AbstractCSharpCodegen extends DefaultCodegen implements CodegenConfig {
@ -562,12 +563,15 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
* @param models list of all models * @param models list of all models
*/ */
protected void updateValueTypeProperty(Map<String, Object> models) { protected void updateValueTypeProperty(Map<String, Object> models) {
// TODO: 5.0: Remove the camelCased vendorExtension within the below loop and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
for (Map.Entry<String, Object> entry : models.entrySet()) { for (Map.Entry<String, Object> entry : models.entrySet()) {
String openAPIName = entry.getKey(); String openAPIName = entry.getKey();
CodegenModel model = ModelUtils.getModelByName(openAPIName, models); CodegenModel model = ModelUtils.getModelByName(openAPIName, models);
if (model != null) { if (model != null) {
for (CodegenProperty var : model.vars) { for (CodegenProperty var : model.vars) {
var.vendorExtensions.put("isValueType", isValueType(var)); var.vendorExtensions.put("isValueType", isValueType(var)); // TODO: 5.0 Remove
var.vendorExtensions.put("x-is-value-type", isValueType(var));
} }
} }
} }

View File

@ -31,6 +31,7 @@ import org.slf4j.LoggerFactory;
import java.util.*; import java.util.*;
import static com.google.common.base.Strings.isNullOrEmpty; import static com.google.common.base.Strings.isNullOrEmpty;
import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.camelize; import static org.openapitools.codegen.utils.StringUtils.camelize;
import static org.openapitools.codegen.utils.StringUtils.underscore; import static org.openapitools.codegen.utils.StringUtils.underscore;
@ -234,16 +235,20 @@ public abstract class AbstractEiffelCodegen extends DefaultCodegen implements Co
char firstChar = parameter.paramName.charAt(0); char firstChar = parameter.paramName.charAt(0);
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
if (Character.isUpperCase(firstChar)) { if (Character.isUpperCase(firstChar)) {
// First char is already uppercase, just use paramName. // First char is already uppercase, just use paramName.
parameter.vendorExtensions.put("x-exportParamName", parameter.paramName); parameter.vendorExtensions.put("x-exportParamName", parameter.paramName); // TODO: 5.0 Remove
parameter.vendorExtensions.put("x-export-param-name", parameter.paramName);
} }
// It's a lowercase first char, let's convert it to uppercase // It's a lowercase first char, let's convert it to uppercase
StringBuilder sb = new StringBuilder(parameter.paramName); StringBuilder sb = new StringBuilder(parameter.paramName);
sb.setCharAt(0, Character.toUpperCase(firstChar)); sb.setCharAt(0, Character.toUpperCase(firstChar));
parameter.vendorExtensions.put("x-exportParamName", sb.toString()); parameter.vendorExtensions.put("x-exportParamName", sb.toString()); // TODO: 5.0 Remove
parameter.vendorExtensions.put("x-export-param-name", sb.toString());
} }
@Override @Override

View File

@ -29,6 +29,7 @@ import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.util.*; import java.util.*;
import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.camelize; import static org.openapitools.codegen.utils.StringUtils.camelize;
import static org.openapitools.codegen.utils.StringUtils.underscore; import static org.openapitools.codegen.utils.StringUtils.underscore;
@ -388,6 +389,10 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
Map<String, Object> objectMap = (Map<String, Object>) objs.get("operations"); Map<String, Object> objectMap = (Map<String, Object>) objs.get("operations");
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
List<CodegenOperation> operations = (List<CodegenOperation>) objectMap.get("operation"); List<CodegenOperation> operations = (List<CodegenOperation>) objectMap.get("operation");
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
for (CodegenOperation operation : operations) { for (CodegenOperation operation : operations) {
// http method verb conversion (e.g. PUT => Put) // http method verb conversion (e.g. PUT => Put)
operation.httpMethod = camelize(operation.httpMethod.toLowerCase(Locale.ROOT)); operation.httpMethod = camelize(operation.httpMethod.toLowerCase(Locale.ROOT));
@ -450,13 +455,16 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
imports.add(createMapping("import", "github.com/antihax/optional")); imports.add(createMapping("import", "github.com/antihax/optional"));
addedOptionalImport = true; addedOptionalImport = true;
} }
// We need to specially map Time type to the optionals package // We need to specially map Time type to the optionals package
if ("time.Time".equals(param.dataType)) { if ("time.Time".equals(param.dataType)) {
param.vendorExtensions.put("x-optionalDataType", "Time"); param.vendorExtensions.put("x-optionalDataType", "Time"); // TODO: 5.0 Remove
param.vendorExtensions.put("x-optional-data-type", "Time");
} else { } else {
// Map optional type to dataType // Map optional type to dataType
param.vendorExtensions.put("x-optionalDataType", String optionalType = param.dataType.substring(0, 1).toUpperCase(Locale.ROOT) + param.dataType.substring(1);
param.dataType.substring(0, 1).toUpperCase(Locale.ROOT) + param.dataType.substring(1)); param.vendorExtensions.put("x-optionalDataType", optionalType); // TODO: 5.0 Remove
param.vendorExtensions.put("x-optional-data-type", optionalType);
} }
} }
@ -464,12 +472,14 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
char nameFirstChar = param.paramName.charAt(0); char nameFirstChar = param.paramName.charAt(0);
if (Character.isUpperCase(nameFirstChar)) { if (Character.isUpperCase(nameFirstChar)) {
// First char is already uppercase, just use paramName. // First char is already uppercase, just use paramName.
param.vendorExtensions.put("x-exportParamName", param.paramName); param.vendorExtensions.put("x-exportParamName", param.paramName); // TODO: 5.0 Remove
param.vendorExtensions.put("x-export-param-name", param.paramName);
} else { } else {
// It's a lowercase first char, let's convert it to uppercase // It's a lowercase first char, let's convert it to uppercase
StringBuilder sb = new StringBuilder(param.paramName); StringBuilder sb = new StringBuilder(param.paramName);
sb.setCharAt(0, Character.toUpperCase(nameFirstChar)); sb.setCharAt(0, Character.toUpperCase(nameFirstChar));
param.vendorExtensions.put("x-exportParamName", sb.toString()); param.vendorExtensions.put("x-exportParamName", sb.toString()); // TODO: 5.0 Remove
param.vendorExtensions.put("x-x-export-param-name", sb.toString());
} }
} }
@ -502,16 +512,22 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
} }
private void setExportParameterName(List<CodegenParameter> codegenParameters) { private void setExportParameterName(List<CodegenParameter> codegenParameters) {
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
for (CodegenParameter param : codegenParameters) { for (CodegenParameter param : codegenParameters) {
char nameFirstChar = param.paramName.charAt(0); char nameFirstChar = param.paramName.charAt(0);
if (Character.isUpperCase(nameFirstChar)) { if (Character.isUpperCase(nameFirstChar)) {
// First char is already uppercase, just use paramName. // First char is already uppercase, just use paramName.
param.vendorExtensions.put("x-exportParamName", param.paramName); param.vendorExtensions.put("x-exportParamName", param.paramName); // TODO: 5.0 Remove
param.vendorExtensions.put("x-export-param-name", param.paramName);
} else { } else {
// It's a lowercase first char, let's convert it to uppercase // It's a lowercase first char, let's convert it to uppercase
StringBuilder sb = new StringBuilder(param.paramName); StringBuilder sb = new StringBuilder(param.paramName);
sb.setCharAt(0, Character.toUpperCase(nameFirstChar)); sb.setCharAt(0, Character.toUpperCase(nameFirstChar));
param.vendorExtensions.put("x-exportParamName", sb.toString()); param.vendorExtensions.put("x-exportParamName", sb.toString()); // TODO: 5.0 Remove
param.vendorExtensions.put("x-export-param-name", sb.toString());
} }
} }
} }

View File

@ -39,6 +39,7 @@ import java.io.File;
import java.util.*; import java.util.*;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.*; import static org.openapitools.codegen.utils.StringUtils.*;
public abstract class AbstractJavaCodegen extends DefaultCodegen implements CodegenConfig { public abstract class AbstractJavaCodegen extends DefaultCodegen implements CodegenConfig {
@ -998,8 +999,13 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
public void postProcessModelProperty(CodegenModel model, CodegenProperty property) { public void postProcessModelProperty(CodegenModel model, CodegenProperty property) {
if (serializeBigDecimalAsString) { if (serializeBigDecimalAsString) {
if (property.baseType.equals("BigDecimal")) { if (property.baseType.equals("BigDecimal")) {
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
// we serialize BigDecimal as `string` to avoid precision loss // we serialize BigDecimal as `string` to avoid precision loss
property.vendorExtensions.put("extraAnnotation", "@JsonSerialize(using = ToStringSerializer.class)"); property.vendorExtensions.put("extraAnnotation", "@JsonSerialize(using = ToStringSerializer.class)"); // TODO: 5.0 Remove
property.vendorExtensions.put("x-extra-annotation", "@JsonSerialize(using = ToStringSerializer.class)");
// this requires some more imports to be added for this model... // this requires some more imports to be added for this model...
model.imports.add("ToStringSerializer"); model.imports.add("ToStringSerializer");

View File

@ -31,6 +31,7 @@ import java.util.*;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.camelize; import static org.openapitools.codegen.utils.StringUtils.camelize;
import static org.openapitools.codegen.utils.StringUtils.underscore; import static org.openapitools.codegen.utils.StringUtils.underscore;
@ -668,10 +669,15 @@ public abstract class AbstractPhpCodegen extends DefaultCodegen implements Codeg
public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) { public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) {
Map<String, Object> operations = (Map<String, Object>) objs.get("operations"); Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation"); List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
for (CodegenOperation op : operationList) { for (CodegenOperation op : operationList) {
// for API test method name // for API test method name
// e.g. public function test{{vendorExtensions.x-testOperationId}}() // e.g. public function test{{vendorExtensions.x-testOperationId}}()
op.vendorExtensions.put("x-testOperationId", camelize(op.operationId)); op.vendorExtensions.put("x-testOperationId", camelize(op.operationId)); // TODO: 5.0 Remove
op.vendorExtensions.put("x-test-operation-id", camelize(op.operationId));
} }
return objs; return objs;
} }

View File

@ -19,12 +19,18 @@ package org.openapitools.codegen.languages;
import org.openapitools.codegen.*; import org.openapitools.codegen.*;
import org.openapitools.codegen.meta.features.*; import org.openapitools.codegen.meta.features.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*; import java.util.*;
import static org.openapitools.codegen.utils.OnceLogger.once;
public class Apache2ConfigCodegen extends DefaultCodegen implements CodegenConfig { public class Apache2ConfigCodegen extends DefaultCodegen implements CodegenConfig {
public static final String USER_INFO_PATH = "userInfoPath"; public static final String USER_INFO_PATH = "userInfoPath";
private static final Logger LOGGER = LoggerFactory.getLogger(Apache2ConfigCodegen.class);
protected String userInfoPath = "/var/www/html/"; protected String userInfoPath = "/var/www/html/";
@Override @Override
@ -89,6 +95,10 @@ public class Apache2ConfigCodegen extends DefaultCodegen implements CodegenConfi
Map<String, Object> operations = (Map<String, Object>) objs.get("operations"); Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation"); List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");
List<CodegenOperation> newOpList = new ArrayList<CodegenOperation>(); List<CodegenOperation> newOpList = new ArrayList<CodegenOperation>();
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
for (CodegenOperation op : operationList) { for (CodegenOperation op : operationList) {
String path = op.path; String path = op.path;
@ -101,7 +111,8 @@ public class Apache2ConfigCodegen extends DefaultCodegen implements CodegenConfi
splitPath.add(item); splitPath.add(item);
op.path += item + "/"; op.path += item + "/";
} }
op.vendorExtensions.put("x-codegen-userInfoPath", userInfoPath); op.vendorExtensions.put("x-codegen-userInfoPath", userInfoPath); // TODO: 5.0 Remove
op.vendorExtensions.put("x-codegen-user-info-path", userInfoPath);
boolean foundInNewList = false; boolean foundInNewList = false;
for (CodegenOperation op1 : newOpList) { for (CodegenOperation op1 : newOpList) {
if (!foundInNewList) { if (!foundInNewList) {
@ -113,7 +124,8 @@ public class Apache2ConfigCodegen extends DefaultCodegen implements CodegenConfi
} }
op.operationIdCamelCase = op1.operationIdCamelCase; op.operationIdCamelCase = op1.operationIdCamelCase;
currentOtherMethodList.add(op); currentOtherMethodList.add(op);
op1.vendorExtensions.put("x-codegen-otherMethods", currentOtherMethodList); op1.vendorExtensions.put("x-codegen-otherMethods", currentOtherMethodList); // TODO: 5.0 Remove
op1.vendorExtensions.put("x-codegen-other-methods", currentOtherMethodList);
} }
} }
} }

View File

@ -27,14 +27,18 @@ import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.*; import org.openapitools.codegen.*;
import org.openapitools.codegen.meta.features.*; import org.openapitools.codegen.meta.features.*;
import org.openapitools.codegen.utils.ModelUtils; import org.openapitools.codegen.utils.ModelUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.util.*; import java.util.*;
import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.dashize; import static org.openapitools.codegen.utils.StringUtils.dashize;
import static org.openapitools.codegen.utils.StringUtils.underscore; import static org.openapitools.codegen.utils.StringUtils.underscore;
public class ClojureClientCodegen extends DefaultCodegen implements CodegenConfig { public class ClojureClientCodegen extends DefaultCodegen implements CodegenConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(ClojureClientCodegen.class);
private static final String PROJECT_NAME = "projectName"; private static final String PROJECT_NAME = "projectName";
private static final String PROJECT_DESCRIPTION = "projectDescription"; private static final String PROJECT_DESCRIPTION = "projectDescription";
private static final String PROJECT_VERSION = "projectVersion"; private static final String PROJECT_VERSION = "projectVersion";
@ -43,7 +47,8 @@ public class ClojureClientCodegen extends DefaultCodegen implements CodegenConfi
private static final String PROJECT_LICENSE_URL = "projectLicenseUrl"; private static final String PROJECT_LICENSE_URL = "projectLicenseUrl";
private static final String BASE_NAMESPACE = "baseNamespace"; private static final String BASE_NAMESPACE = "baseNamespace";
static final String X_BASE_SPEC = "x-baseSpec"; static final String X_BASE_SPEC = "x-baseSpec"; // TODO: 5.0 Remove
static final String VENDOR_EXTENSION_X_BASE_SPEC = "x-base-spec";
static final String X_MODELS = "x-models"; static final String X_MODELS = "x-models";
protected String projectName; protected String projectName;
@ -198,19 +203,16 @@ public class ClojureClientCodegen extends DefaultCodegen implements CodegenConfi
public CodegenModel fromModel(String name, Schema mod) { public CodegenModel fromModel(String name, Schema mod) {
CodegenModel model = super.fromModel(name, mod); CodegenModel model = super.fromModel(name, mod);
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
// If a var is a base spec we won't need to import it // If a var is a base spec we won't need to import it
for (CodegenProperty var : model.vars) { for (CodegenProperty var : model.vars) {
if (baseSpecs.contains(var.complexType)) { var.vendorExtensions.put(X_BASE_SPEC, baseSpecs.contains(var.complexType)); // TODO: 5.0 Remove
var.vendorExtensions.put(X_BASE_SPEC, true); var.vendorExtensions.put(VENDOR_EXTENSION_X_BASE_SPEC, baseSpecs.contains(var.complexType));
} else {
var.vendorExtensions.put(X_BASE_SPEC, false);
}
if (var.items != null) { if (var.items != null) {
if (baseSpecs.contains(var.items.complexType)) { var.items.vendorExtensions.put(X_BASE_SPEC, baseSpecs.contains(var.items.complexType)); // TODO: 5.0 Remove
var.items.vendorExtensions.put(X_BASE_SPEC, true); var.items.vendorExtensions.put(VENDOR_EXTENSION_X_BASE_SPEC, baseSpecs.contains(var.items.complexType));
} else {
var.items.vendorExtensions.put(X_BASE_SPEC, false);
}
} }
} }

View File

@ -32,6 +32,7 @@ import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.util.*; import java.util.*;
import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.*; import static org.openapitools.codegen.utils.StringUtils.*;
public class CppPistacheServerCodegen extends AbstractCppCodegen { public class CppPistacheServerCodegen extends AbstractCppCodegen {
@ -245,6 +246,9 @@ public class CppPistacheServerCodegen extends AbstractCppCodegen {
operations.put("classnameSnakeUpperCase", underscore(classname).toUpperCase(Locale.ROOT)); operations.put("classnameSnakeUpperCase", underscore(classname).toUpperCase(Locale.ROOT));
operations.put("classnameSnakeLowerCase", underscore(classname).toLowerCase(Locale.ROOT)); operations.put("classnameSnakeLowerCase", underscore(classname).toLowerCase(Locale.ROOT));
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation"); List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");
for (CodegenOperation op : operationList) { for (CodegenOperation op : operationList) {
boolean consumeJson = false; boolean consumeJson = false;
@ -254,7 +258,9 @@ public class CppPistacheServerCodegen extends AbstractCppCodegen {
op.bodyParam.vendorExtensions = new HashMap<>(); op.bodyParam.vendorExtensions = new HashMap<>();
} }
op.bodyParam.vendorExtensions.put("x-codegen-pistache-isStringOrDate", op.bodyParam.isString || op.bodyParam.isDate); boolean isStringOrDate = op.bodyParam.isString || op.bodyParam.isDate;
op.bodyParam.vendorExtensions.put("x-codegen-pistache-isStringOrDate", isStringOrDate); // TODO: 5.0 Remove
op.bodyParam.vendorExtensions.put("x-codegen-pistache-is-string-or-date", isStringOrDate);
} }
if (op.consumes != null) { if (op.consumes != null) {
for (Map<String, String> consume : op.consumes) { for (Map<String, String> consume : op.consumes) {
@ -288,8 +294,10 @@ public class CppPistacheServerCodegen extends AbstractCppCodegen {
if (op.vendorExtensions == null) { if (op.vendorExtensions == null) {
op.vendorExtensions = new HashMap<>(); op.vendorExtensions = new HashMap<>();
} }
op.vendorExtensions.put("x-codegen-pistache-consumesJson", consumeJson); op.vendorExtensions.put("x-codegen-pistache-consumesJson", consumeJson); // TODO: 5.0 Remove
op.vendorExtensions.put("x-codegen-pistache-isParsingSupported", isParsingSupported); op.vendorExtensions.put("x-codegen-pistache-consumes-json", consumeJson);
op.vendorExtensions.put("x-codegen-pistache-isParsingSupported", isParsingSupported); // TODO: 5.0 Remove
op.vendorExtensions.put("x-codegen-pistache-is-parsing-supported", isParsingSupported);
// Check if any one of the operations needs a model, then at API file level, at least one model has to be included. // Check if any one of the operations needs a model, then at API file level, at least one model has to be included.
for(String hdr : op.imports) { for(String hdr : op.imports) {

View File

@ -11,12 +11,16 @@ import org.openapitools.codegen.CodegenOperation;
import org.openapitools.codegen.CodegenParameter; import org.openapitools.codegen.CodegenParameter;
import org.openapitools.codegen.meta.features.*; import org.openapitools.codegen.meta.features.*;
import org.openapitools.codegen.utils.ModelUtils; import org.openapitools.codegen.utils.ModelUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.util.*; import java.util.*;
public class CppQt5AbstractCodegen extends AbstractCppCodegen implements CodegenConfig { import static org.openapitools.codegen.utils.OnceLogger.once;
public class CppQt5AbstractCodegen extends AbstractCppCodegen implements CodegenConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(CppQt5AbstractCodegen.class);
protected final String PREFIX = "OAI"; protected final String PREFIX = "OAI";
protected String apiVersion = "1.0.0"; protected String apiVersion = "1.0.0";
protected static final String CPP_NAMESPACE = "cppNamespace"; protected static final String CPP_NAMESPACE = "cppNamespace";
@ -314,6 +318,10 @@ public class CppQt5AbstractCodegen extends AbstractCppCodegen implements Codegen
List<Map<String, String>> imports = (List<Map<String, String>>) objs.get("imports"); List<Map<String, String>> imports = (List<Map<String, String>>) objs.get("imports");
Map<String, CodegenModel> codegenModels = new HashMap<String, CodegenModel> (); Map<String, CodegenModel> codegenModels = new HashMap<String, CodegenModel> ();
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
for(Object moObj : allModels) { for(Object moObj : allModels) {
CodegenModel mo = ((Map<String, CodegenModel>) moObj).get("model"); CodegenModel mo = ((Map<String, CodegenModel>) moObj).get("model");
if(mo.isEnum) { if(mo.isEnum) {
@ -323,7 +331,8 @@ public class CppQt5AbstractCodegen extends AbstractCppCodegen implements Codegen
for (CodegenOperation operation : operations) { for (CodegenOperation operation : operations) {
if(operation.returnType != null) { if(operation.returnType != null) {
if(codegenModels.containsKey(operation.returnType)){ if(codegenModels.containsKey(operation.returnType)){
operation.vendorExtensions.put("returnsEnum", true); operation.vendorExtensions.put("returnsEnum", true); // TODO: 5.0 Remove
operation.vendorExtensions.put("x-returns-enum", true);
} }
} }
// Check all return parameter baseType if there is a necessity to include, include it if not // Check all return parameter baseType if there is a necessity to include, include it if not

View File

@ -29,6 +29,7 @@ import java.io.File;
import java.util.*; import java.util.*;
import java.util.Map.Entry; import java.util.Map.Entry;
import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.*; import static org.openapitools.codegen.utils.StringUtils.*;
public class CppRestbedServerCodegen extends AbstractCppCodegen { public class CppRestbedServerCodegen extends AbstractCppCodegen {
@ -277,6 +278,10 @@ public class CppRestbedServerCodegen extends AbstractCppCodegen {
Map<String, Object> operations = (Map<String, Object>) objs.get("operations"); Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation"); List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");
List<CodegenOperation> newOpList = new ArrayList<CodegenOperation>(); List<CodegenOperation> newOpList = new ArrayList<CodegenOperation>();
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
for (CodegenOperation op : operationList) { for (CodegenOperation op : operationList) {
String path = op.path; String path = op.path;
@ -298,7 +303,9 @@ public class CppRestbedServerCodegen extends AbstractCppCodegen {
} }
op.path += item + "/"; op.path += item + "/";
} }
op.vendorExtensions.put("x-codegen-resourceName", resourceNameCamelCase); op.vendorExtensions.put("x-codegen-resourceName", resourceNameCamelCase); // TODO: 5.0 Remove
op.vendorExtensions.put("x-codegen-resource-name", resourceNameCamelCase);
boolean foundInNewList = false; boolean foundInNewList = false;
for (CodegenOperation op1 : newOpList) { for (CodegenOperation op1 : newOpList) {
if (!foundInNewList) { if (!foundInNewList) {
@ -310,7 +317,8 @@ public class CppRestbedServerCodegen extends AbstractCppCodegen {
} }
op.operationIdCamelCase = op1.operationIdCamelCase; op.operationIdCamelCase = op1.operationIdCamelCase;
currentOtherMethodList.add(op); currentOtherMethodList.add(op);
op1.vendorExtensions.put("x-codegen-otherMethods", currentOtherMethodList); op1.vendorExtensions.put("x-codegen-otherMethods", currentOtherMethodList); // TODO: 5.0 Remove
op1.vendorExtensions.put("x-codegen-other-methods", currentOtherMethodList);
} }
} }
} }

View File

@ -40,6 +40,7 @@ import java.util.Set;
import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.media.Schema;
import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.camelize; import static org.openapitools.codegen.utils.StringUtils.camelize;
import static org.openapitools.codegen.utils.StringUtils.underscore; import static org.openapitools.codegen.utils.StringUtils.underscore;
@ -261,6 +262,10 @@ public class DartDioClientCodegen extends DartClientCodegen {
objs = super.postProcessModels(objs); objs = super.postProcessModels(objs);
List<Object> models = (List<Object>) objs.get("models"); List<Object> models = (List<Object>) objs.get("models");
ProcessUtils.addIndexToProperties(models, 1); ProcessUtils.addIndexToProperties(models, 1);
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
for (Object _mo : models) { for (Object _mo : models) {
Map<String, Object> mo = (Map<String, Object>) _mo; Map<String, Object> mo = (Map<String, Object>) _mo;
Set<String> modelImports = new HashSet<>(); Set<String> modelImports = new HashSet<>();
@ -276,7 +281,9 @@ public class DartDioClientCodegen extends DartClientCodegen {
} }
cm.imports = modelImports; cm.imports = modelImports;
cm.vendorExtensions.put("hasVars", cm.vars.size() > 0); boolean hasVars = cm.vars.size() > 0;
cm.vendorExtensions.put("hasVars", hasVars); // TODO: 5.0 Remove
cm.vendorExtensions.put("x-has-vars", hasVars);
} }
return objs; return objs;
} }
@ -342,9 +349,16 @@ public class DartDioClientCodegen extends DartClientCodegen {
} }
} }
op.vendorExtensions.put("isJson", isJson); // TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
op.vendorExtensions.put("isForm", isForm); once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
op.vendorExtensions.put("isMultipart", isMultipart);
op.vendorExtensions.put("isJson", isJson); // TODO: 5.0 Remove
op.vendorExtensions.put("isForm", isForm); // TODO: 5.0 Remove
op.vendorExtensions.put("isMultipart", isMultipart); // TODO: 5.0 Remove
op.vendorExtensions.put("x-is-json", isJson);
op.vendorExtensions.put("x-is-form", isForm);
op.vendorExtensions.put("x-is-multipart", isMultipart);
if (op.getHasFormParams()) { if (op.getHasFormParams()) {
fullImports.add("package:" + pubName + "/api_util.dart"); fullImports.add("package:" + pubName + "/api_util.dart");

View File

@ -24,13 +24,17 @@ import io.swagger.v3.oas.models.media.*;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.utils.ProcessUtils; import org.openapitools.codegen.utils.ProcessUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.util.*; import java.util.*;
import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.underscore; import static org.openapitools.codegen.utils.StringUtils.underscore;
public class DartJaguarClientCodegen extends DartClientCodegen { public class DartJaguarClientCodegen extends DartClientCodegen {
private static final Logger LOGGER = LoggerFactory.getLogger(DartJaguarClientCodegen.class);
private static final String NULLABLE_FIELDS = "nullableFields"; private static final String NULLABLE_FIELDS = "nullableFields";
private static final String SERIALIZATION_FORMAT = "serialization"; private static final String SERIALIZATION_FORMAT = "serialization";
private static final String IS_FORMAT_JSON = "jsonFormat"; private static final String IS_FORMAT_JSON = "jsonFormat";
@ -220,6 +224,10 @@ public class DartJaguarClientCodegen extends DartClientCodegen {
objs = super.postProcessModels(objs); objs = super.postProcessModels(objs);
List<Object> models = (List<Object>) objs.get("models"); List<Object> models = (List<Object>) objs.get("models");
ProcessUtils.addIndexToProperties(models, 1); ProcessUtils.addIndexToProperties(models, 1);
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
for (Object _mo : models) { for (Object _mo : models) {
Map<String, Object> mo = (Map<String, Object>) _mo; Map<String, Object> mo = (Map<String, Object>) _mo;
Set<String> modelImports = new HashSet<>(); Set<String> modelImports = new HashSet<>();
@ -240,7 +248,9 @@ public class DartJaguarClientCodegen extends DartClientCodegen {
} }
cm.imports = modelImports; cm.imports = modelImports;
cm.vendorExtensions.put("hasVars", cm.vars.size() > 0); boolean hasVars = cm.vars.size() > 0;
cm.vendorExtensions.put("hasVars", hasVars); // TODO: 5.0 Remove
cm.vendorExtensions.put("x-has-vars", hasVars);
} }
return objs; return objs;
} }
@ -248,12 +258,15 @@ public class DartJaguarClientCodegen extends DartClientCodegen {
@Override @Override
public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) { public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) {
objs = super.postProcessOperationsWithModels(objs, allModels); objs = super.postProcessOperationsWithModels(objs, allModels);
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
Map<String, Object> operations = (Map<String, Object>) objs.get("operations"); Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation"); List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");
Set<String> modelImports = new HashSet<>(); Set<String> modelImports = new HashSet<>();
Set<String> fullImports = new HashSet<>(); Set<String> fullImports = new HashSet<>();
for (CodegenOperation op : operationList) { for (CodegenOperation op : operationList) {
op.httpMethod = StringUtils.capitalize(op.httpMethod.toLowerCase(Locale.ROOT)); op.httpMethod = StringUtils.capitalize(op.httpMethod.toLowerCase(Locale.ROOT));
boolean isJson = true; //default to JSON boolean isJson = true; //default to JSON
@ -292,10 +305,16 @@ public class DartJaguarClientCodegen extends DartClientCodegen {
} }
} }
op.vendorExtensions.put("isJson", isJson); op.vendorExtensions.put("isForm", isForm); // TODO: 5.0 Remove
op.vendorExtensions.put("isProto", isProto); op.vendorExtensions.put("isJson", isJson); // TODO: 5.0 Remove
op.vendorExtensions.put("isForm", isForm); op.vendorExtensions.put("isProto", isProto); // TODO: 5.0 Remove
op.vendorExtensions.put("isMultipart", isMultipart); op.vendorExtensions.put("isMultipart", isMultipart); // TODO: 5.0 Remove
op.vendorExtensions.put("x-is-form", isForm);
op.vendorExtensions.put("x-is-json", isJson);
op.vendorExtensions.put("x-is-proto", isProto);
op.vendorExtensions.put("x-is-multipart", isMultipart);
Set<String> imports = new HashSet<>(); Set<String> imports = new HashSet<>();
for (String item : op.imports) { for (String item : op.imports) {

View File

@ -35,6 +35,7 @@ import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.camelize; import static org.openapitools.codegen.utils.StringUtils.camelize;
public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig { public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
@ -47,10 +48,14 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
private static final String ELM_PREFIX_CUSTOM_TYPE_VARIANTS = "elmPrefixCustomTypeVariants"; private static final String ELM_PREFIX_CUSTOM_TYPE_VARIANTS = "elmPrefixCustomTypeVariants";
private static final String ELM_ENABLE_CUSTOM_BASE_PATHS = "elmEnableCustomBasePaths"; private static final String ELM_ENABLE_CUSTOM_BASE_PATHS = "elmEnableCustomBasePaths";
private static final String ELM_ENABLE_HTTP_REQUEST_TRACKERS = "elmEnableHttpRequestTrackers"; private static final String ELM_ENABLE_HTTP_REQUEST_TRACKERS = "elmEnableHttpRequestTrackers";
private static final String ENCODER = "elmEncoder"; private static final String ENCODER = "elmEncoder"; // TODO: 5.0 Remove
private static final String DECODER = "elmDecoder"; private static final String VENDOR_EXTENSION_ENCODER = "x-elm-encoder";
private static final String DISCRIMINATOR_NAME = "discriminatorName"; private static final String DECODER = "elmDecoder"; // TODO: 5.0 Remove
private static final String CUSTOM_TYPE = "elmCustomType"; private static final String VENDOR_EXTENSION_DECODER = "x-elm-decoder";
private static final String DISCRIMINATOR_NAME = "discriminatorName"; // TODO: 5.0 Remove
private static final String VENDOR_EXTENSION_DISCRIMINATOR_NAME = "x-discriminator-name";
private static final String CUSTOM_TYPE = "elmCustomType"; // TODO: 5.0 Remove
private static final String VENDOR_EXTENSION_CUSTOM_TYPE = "x-elm-custom-type";
protected String packageName = "openapi"; protected String packageName = "openapi";
protected String packageVersion = "1.0.0"; protected String packageVersion = "1.0.0";
@ -341,6 +346,10 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
@SuppressWarnings({"static-method", "unchecked"}) @SuppressWarnings({"static-method", "unchecked"})
public Map<String, Object> postProcessAllModels(Map<String, Object> objs) { public Map<String, Object> postProcessAllModels(Map<String, Object> objs) {
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
// Index all CodegenModels by model name. // Index all CodegenModels by model name.
Map<String, CodegenModel> allModels = new HashMap<>(); Map<String, CodegenModel> allModels = new HashMap<>();
for (Map.Entry<String, Object> entry : objs.entrySet()) { for (Map.Entry<String, Object> entry : objs.entrySet()) {
@ -378,7 +387,8 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
CodegenModel cm = (CodegenModel) mo.get("model"); CodegenModel cm = (CodegenModel) mo.get("model");
if (cm.isEnum) { if (cm.isEnum) {
addEncoderAndDecoder(cm.vendorExtensions, cm.classname, DataTypeExposure.EXPOSED); addEncoderAndDecoder(cm.vendorExtensions, cm.classname, DataTypeExposure.EXPOSED);
cm.vendorExtensions.put(CUSTOM_TYPE, cm.classname); cm.vendorExtensions.put(CUSTOM_TYPE, cm.classname); // TODO: 5.0 Remove
cm.vendorExtensions.put(VENDOR_EXTENSION_CUSTOM_TYPE, cm.classname);
} else if (cm.isAlias) { } else if (cm.isAlias) {
addEncoderAndDecoder(cm.vendorExtensions, cm.dataType, DataTypeExposure.EXPOSED); addEncoderAndDecoder(cm.vendorExtensions, cm.dataType, DataTypeExposure.EXPOSED);
} }
@ -416,7 +426,8 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
child.allVars.clear(); child.allVars.clear();
child.allVars.addAll(allVars); child.allVars.addAll(allVars);
child.vendorExtensions.put(DISCRIMINATOR_NAME, propertyName); child.vendorExtensions.put(DISCRIMINATOR_NAME, propertyName); // TODO: 5.0 Remove
child.vendorExtensions.put(VENDOR_EXTENSION_DISCRIMINATOR_NAME, propertyName);
} }
} }
inner.put("elmImports", elmImports); inner.put("elmImports", elmImports);
@ -464,6 +475,9 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
Map<String, Object> objs = (Map<String, Object>) operations.get("operations"); Map<String, Object> objs = (Map<String, Object>) operations.get("operations");
List<CodegenOperation> ops = (List<CodegenOperation>) objs.get("operation"); List<CodegenOperation> ops = (List<CodegenOperation>) objs.get("operation");
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
final Set<String> dependencies = new HashSet<>(); final Set<String> dependencies = new HashSet<>();
for (CodegenOperation op : ops) { for (CodegenOperation op : ops) {
@ -484,7 +498,8 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
} }
}) })
.collect(Collectors.toList()); .collect(Collectors.toList());
op.vendorExtensions.put("pathParams", pathParams); op.vendorExtensions.put("pathParams", pathParams); // TODO: 5.0 Remove
op.vendorExtensions.put("x-path-params", pathParams);
} }
for (CodegenParameter param : op.allParams) { for (CodegenParameter param : op.allParams) {
@ -677,9 +692,13 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
public CodegenProperty fromProperty(String name, Schema p) { public CodegenProperty fromProperty(String name, Schema p) {
final CodegenProperty property = super.fromProperty(name, p); final CodegenProperty property = super.fromProperty(name, p);
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
if (property.isEnum) { if (property.isEnum) {
addEncoderAndDecoder(property.vendorExtensions, property.baseName, DataTypeExposure.INTERNAL); addEncoderAndDecoder(property.vendorExtensions, property.baseName, DataTypeExposure.INTERNAL);
property.vendorExtensions.put(CUSTOM_TYPE, property.datatypeWithEnum); property.vendorExtensions.put(CUSTOM_TYPE, property.datatypeWithEnum); // TODO: 5.0 Remove
property.vendorExtensions.put(VENDOR_EXTENSION_CUSTOM_TYPE, property.datatypeWithEnum);
} else { } else {
final boolean isPrimitiveType = property.isMapContainer ? isPrimitiveDataType(property.dataType) : property.isPrimitiveType; final boolean isPrimitiveType = property.isMapContainer ? isPrimitiveDataType(property.dataType) : property.isPrimitiveType;
addEncoderAndDecoder(property.vendorExtensions, property.dataType, isPrimitiveType ? DataTypeExposure.PRIMITIVE : DataTypeExposure.EXTERNAL); addEncoderAndDecoder(property.vendorExtensions, property.dataType, isPrimitiveType ? DataTypeExposure.PRIMITIVE : DataTypeExposure.EXTERNAL);
@ -758,12 +777,12 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig {
encodeName = ""; encodeName = "";
decoderName = ""; decoderName = "";
} }
if (!vendorExtensions.containsKey(ENCODER)) {
vendorExtensions.put(ENCODER, encodeName); vendorExtensions.putIfAbsent(ENCODER, encodeName); // TODO: 5.0 Remove
} vendorExtensions.putIfAbsent(VENDOR_EXTENSION_ENCODER, encodeName);
if (!vendorExtensions.containsKey(DECODER)) {
vendorExtensions.put(DECODER, decoderName); vendorExtensions.putIfAbsent(DECODER, decoderName); // TODO: 5.0 Remove
} vendorExtensions.putIfAbsent(VENDOR_EXTENSION_DECODER, decoderName);
} }
private enum DataTypeExposure { private enum DataTypeExposure {

View File

@ -38,6 +38,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.camelize; import static org.openapitools.codegen.utils.StringUtils.camelize;
import static org.openapitools.codegen.utils.StringUtils.underscore; import static org.openapitools.codegen.utils.StringUtils.underscore;
@ -87,40 +88,74 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
static final String MIME_ANY = "MimeAny"; static final String MIME_ANY = "MimeAny";
// vendor extensions // vendor extensions
static final String X_ALL_UNIQUE_PARAMS = "x-allUniqueParams"; static final String X_ALL_UNIQUE_PARAMS = "x-allUniqueParams"; // TODO: 5.0 Remove
static final String X_ALL_IMPORT_MAPPINGS = "x-allImportMappings"; static final String X_ALL_IMPORT_MAPPINGS = "x-allImportMappings"; // TODO: 5.0 Remove
static final String X_ALL_UNIQUE_IMPORT_PATHS = "x-allUniqueImportPaths"; static final String X_ALL_UNIQUE_IMPORT_PATHS = "x-allUniqueImportPaths"; // TODO: 5.0 Remove
static final String X_COLLECTION_FORMAT = "x-collectionFormat"; static final String X_COLLECTION_FORMAT = "x-collectionFormat"; // TODO: 5.0 Remove
static final String X_HADDOCK_PATH = "x-haddockPath"; static final String X_HADDOCK_PATH = "x-haddockPath"; // TODO: 5.0 Remove
static final String X_HAS_BODY_OR_FORM_PARAM = "x-hasBodyOrFormParam"; static final String X_HAS_BODY_OR_FORM_PARAM = "x-hasBodyOrFormParam"; // TODO: 5.0 Remove
static final String X_HAS_ENUM_SECTION = "x-hasEnumSection"; static final String X_HAS_ENUM_SECTION = "x-hasEnumSection"; // TODO: 5.0 Remove
static final String X_HAS_IMPORT_MAPPINGS = "x-hasImportMappings"; static final String X_HAS_IMPORT_MAPPINGS = "x-hasImportMappings"; // TODO: 5.0 Remove
static final String X_HAS_MIME_FORM_URL_ENCODED = "x-hasMimeFormUrlEncoded"; static final String X_HAS_MIME_FORM_URL_ENCODED = "x-hasMimeFormUrlEncoded"; // TODO: 5.0 Remove
static final String X_HAS_NEW_TAG = "x-hasNewTag"; static final String X_HAS_NEW_TAG = "x-hasNewTag"; // TODO: 5.0 Remove
static final String X_HAS_OPTIONAL_PARAMS = "x-hasOptionalParams"; static final String X_HAS_OPTIONAL_PARAMS = "x-hasOptionalParams"; // TODO: 5.0 Remove
static final String X_HAS_UNKNOWN_MIME_TYPES = "x-hasUnknownMimeTypes"; static final String X_HAS_UNKNOWN_MIME_TYPES = "x-hasUnknownMimeTypes"; // TODO: 5.0 Remove
static final String X_HAS_UNKNOWN_RETURN = "x-hasUnknownReturn"; static final String X_HAS_UNKNOWN_RETURN = "x-hasUnknownReturn"; // TODO: 5.0 Remove
static final String X_INLINE_CONTENT_TYPE = "x-inlineContentType"; static final String X_INLINE_CONTENT_TYPE = "x-inlineContentType"; // TODO: 5.0 Remove
static final String X_INLINE_ACCEPT = "x-inlineAccept"; static final String X_INLINE_ACCEPT = "x-inlineAccept"; // TODO: 5.0 Remove
static final String X_IS_BODY_OR_FORM_PARAM = "x-isBodyOrFormParam"; static final String X_IS_BODY_OR_FORM_PARAM = "x-isBodyOrFormParam"; // TODO: 5.0 Remove
static final String X_IS_BODY_PARAM = "x-isBodyParam"; static final String X_IS_BODY_PARAM = "x-isBodyParam"; // TODO: 5.0 Remove
static final String X_IS_MAYBE_VALUE = "x-isMaybeValue"; static final String X_IS_MAYBE_VALUE = "x-isMaybeValue"; // TODO: 5.0 Remove
static final String X_MEDIA_DATA_TYPE = "x-mediaDataType"; static final String X_MEDIA_DATA_TYPE = "x-mediaDataType"; // TODO: 5.0 Remove
static final String X_DATA_TYPE = "x-dataType"; static final String X_DATA_TYPE = "x-dataType"; // TODO: 5.0 Remove
static final String X_ENUM_VALUES = "x-enumValues"; static final String X_ENUM_VALUES = "x-enumValues"; // TODO: 5.0 Remove
static final String X_MEDIA_IS_JSON = "x-mediaIsJson"; static final String X_MEDIA_IS_JSON = "x-mediaIsJson"; // TODO: 5.0 Remove
static final String X_MEDIA_IS_WILDCARD = "x-mediaIsWildcard"; static final String X_MEDIA_IS_WILDCARD = "x-mediaIsWildcard"; // TODO: 5.0 Remove
static final String X_MIME_TYPES = "x-mimeTypes"; static final String X_MIME_TYPES = "x-mimeTypes"; // TODO: 5.0 Remove
static final String X_OPERATION_TYPE = "x-operationType"; static final String X_OPERATION_TYPE = "x-operationType"; // TODO: 5.0 Remove
static final String X_PARAM_NAME_TYPE = "x-paramNameType"; static final String X_PARAM_NAME_TYPE = "x-paramNameType"; // TODO: 5.0 Remove
static final String X_PATH = "x-path"; static final String X_RETURN_TYPE = "x-returnType"; // TODO: 5.0 Remove
static final String X_RETURN_TYPE = "x-returnType"; static final String X_STRICT_FIELDS = "x-strictFields"; // TODO: 5.0 Remove
static final String X_STRICT_FIELDS = "x-strictFields"; static final String X_UNKNOWN_MIME_TYPES = "x-unknownMimeTypes"; // TODO: 5.0 Remove
static final String X_UNKNOWN_MIME_TYPES = "x-unknownMimeTypes"; static final String X_USE_KATIP = "x-useKatip"; // TODO: 5.0 Remove
static final String X_USE_KATIP = "x-useKatip"; static final String X_ALLOW_NONUNIQUE_OPERATION_IDS = "x-allowNonUniqueOperationIds"; // TODO: 5.0 Remove
static final String X_ALLOW_NONUNIQUE_OPERATION_IDS = "x-allowNonUniqueOperationIds";
static final String VENDOR_EXTENSION_X_ALL_UNIQUE_PARAMS = "x-all-unique-params";
static final String VENDOR_EXTENSION_X_ALL_IMPORT_MAPPINGS = "x-all-import-mappings";
static final String VENDOR_EXTENSION_X_ALL_UNIQUE_IMPORT_PATHS = "x-all-unique-import-paths";
static final String VENDOR_EXTENSION_X_COLLECTION_FORMAT = "x-collection-format";
static final String VENDOR_EXTENSION_X_HADDOCK_PATH = "x-haddock-path";
static final String VENDOR_EXTENSION_X_HAS_BODY_OR_FORM_PARAM = "x-has-body-or-form-param";
static final String VENDOR_EXTENSION_X_HAS_ENUM_SECTION = "x-has-enum-section";
static final String VENDOR_EXTENSION_X_HAS_IMPORT_MAPPINGS = "x-has-import-mappings";
static final String VENDOR_EXTENSION_X_HAS_MIME_FORM_URL_ENCODED = "x-has-mime-form-url-encoded";
static final String VENDOR_EXTENSION_X_HAS_NEW_TAG = "x-has-new-tag";
static final String VENDOR_EXTENSION_X_HAS_OPTIONAL_PARAMS = "x-has-optional-params";
static final String VENDOR_EXTENSION_X_HAS_UNKNOWN_MIME_TYPES = "x-has-unknown-mime-types";
static final String VENDOR_EXTENSION_X_HAS_UNKNOWN_RETURN = "x-has-unknown-return";
static final String VENDOR_EXTENSION_X_INLINE_CONTENT_TYPE = "x-inline-content-type";
static final String VENDOR_EXTENSION_X_INLINE_ACCEPT = "x-inline-accept";
static final String VENDOR_EXTENSION_X_IS_BODY_OR_FORM_PARAM = "x-is-body-or-form-param";
static final String VENDOR_EXTENSION_X_IS_BODY_PARAM = "x-is-body-param";
static final String VENDOR_EXTENSION_X_IS_MAYBE_VALUE = "x-is-maybe-value";
static final String VENDOR_EXTENSION_X_MEDIA_DATA_TYPE = "x-media-data-type";
static final String VENDOR_EXTENSION_X_DATA_TYPE = "x-data-type";
static final String VENDOR_EXTENSION_X_ENUM_VALUES = "x-enum-values";
static final String VENDOR_EXTENSION_X_MEDIA_IS_JSON = "x-media-is-json";
static final String VENDOR_EXTENSION_X_MEDIA_IS_WILDCARD = "x-media-is-wildcard";
static final String VENDOR_EXTENSION_X_MIME_TYPES = "x-mime-types";
static final String VENDOR_EXTENSION_X_OPERATION_TYPE = "x-operation-type";
static final String VENDOR_EXTENSION_X_PARAM_NAME_TYPE = "x-param-name-type";
static final String VENDOR_EXTENSION_X_RETURN_TYPE = "x-return-type";
static final String VENDOR_EXTENSION_X_STRICT_FIELDS = "x-strict-fields";
static final String VENDOR_EXTENSION_X_UNKNOWN_MIME_TYPES = "x-unknown-mime-types";
static final String VENDOR_EXTENSION_X_USE_KATIP = "x-use-katip";
static final String VENDOR_EXTENSION_X_ALLOW_NONUNIQUE_OPERATION_IDS = "x-allow-non-unique-operation-ids";
// note; newtype is a single lowercase word in Haskell (not separated by hyphen)
static final String X_NEWTYPE = "x-newtype"; static final String X_NEWTYPE = "x-newtype";
static final String X_ENUM = "x-enum"; static final String VENDOR_EXTENSION_X_ENUM = "x-enum";
static final String VENDOR_EXTENSION_X_PATH = "x-path";
protected ArrayList<Map<String, String>> unknownMimeTypes = new ArrayList<>(); protected ArrayList<Map<String, String>> unknownMimeTypes = new ArrayList<>();
protected Map<String, Map<String, Object>> uniqueParamNameTypes = new HashMap<>(); protected Map<String, Map<String, Object>> uniqueParamNameTypes = new HashMap<>();
@ -664,6 +699,9 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
@Override @Override
public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation op, Map<String, List<CodegenOperation>> operations) { public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation op, Map<String, List<CodegenOperation>> operations) {
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
List<CodegenOperation> opList = operations.get(tag); List<CodegenOperation> opList = operations.get(tag);
if (opList == null || opList.isEmpty()) { if (opList == null || opList.isEmpty()) {
opList = new ArrayList<CodegenOperation>(); opList = new ArrayList<CodegenOperation>();
@ -700,25 +738,33 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
op.vendorExtensions = new LinkedHashMap(); op.vendorExtensions = new LinkedHashMap();
String operationType = toTypeName("Op", op.operationId); String operationType = toTypeName("Op", op.operationId);
op.vendorExtensions.put(X_OPERATION_TYPE, operationType); op.vendorExtensions.put(X_OPERATION_TYPE, operationType); // TODO: 5.0 Remove
op.vendorExtensions.put(VENDOR_EXTENSION_X_OPERATION_TYPE, operationType);
typeNames.add(operationType); typeNames.add(operationType);
op.vendorExtensions.put(X_HADDOCK_PATH, String.format(Locale.ROOT, "%s %s", op.httpMethod, op.path.replace("/", "\\/"))); op.vendorExtensions.put(X_HADDOCK_PATH, String.format(Locale.ROOT, "%s %s", op.httpMethod, op.path.replace("/", "\\/"))); // TODO: 5.0 Remove
op.vendorExtensions.put(X_HAS_BODY_OR_FORM_PARAM, op.getHasBodyParam() || op.getHasFormParams()); op.vendorExtensions.put(VENDOR_EXTENSION_X_HADDOCK_PATH, String.format(Locale.ROOT, "%s %s", op.httpMethod, op.path.replace("/", "\\/")));
op.vendorExtensions.put(X_HAS_BODY_OR_FORM_PARAM, op.getHasBodyParam() || op.getHasFormParams()); // TODO: 5.0 Remove
op.vendorExtensions.put(VENDOR_EXTENSION_X_HAS_BODY_OR_FORM_PARAM, op.getHasBodyParam() || op.getHasFormParams());
for (CodegenParameter param : op.allParams) { for (CodegenParameter param : op.allParams) {
param.vendorExtensions = new LinkedHashMap(); // prevent aliasing/sharing param.vendorExtensions = new LinkedHashMap(); // prevent aliasing/sharing
param.vendorExtensions.put(X_OPERATION_TYPE, operationType); param.vendorExtensions.put(X_OPERATION_TYPE, operationType); // TODO: 5.0 Remove
param.vendorExtensions.put(X_IS_BODY_OR_FORM_PARAM, param.isBodyParam || param.isFormParam); param.vendorExtensions.put(VENDOR_EXTENSION_X_OPERATION_TYPE, operationType);
param.vendorExtensions.put(X_IS_BODY_OR_FORM_PARAM, param.isBodyParam || param.isFormParam); // TODO: 5.0 Remove
param.vendorExtensions.put(VENDOR_EXTENSION_X_IS_BODY_OR_FORM_PARAM, param.isBodyParam || param.isFormParam);
if (!StringUtils.isBlank(param.collectionFormat)) { if (!StringUtils.isBlank(param.collectionFormat)) {
param.vendorExtensions.put(X_COLLECTION_FORMAT, mapCollectionFormat(param.collectionFormat)); param.vendorExtensions.put(X_COLLECTION_FORMAT, mapCollectionFormat(param.collectionFormat)); // TODO: 5.0 Remove
param.vendorExtensions.put(VENDOR_EXTENSION_X_COLLECTION_FORMAT, mapCollectionFormat(param.collectionFormat));
} else if (!param.isBodyParam && (param.isListContainer || param.dataType.startsWith("["))) { // param.isListContainer is sometimes false for list types } else if (!param.isBodyParam && (param.isListContainer || param.dataType.startsWith("["))) { // param.isListContainer is sometimes false for list types
// defaulting due to https://github.com/wing328/openapi-generator/issues/72 // defaulting due to https://github.com/wing328/openapi-generator/issues/72
param.collectionFormat = "csv"; param.collectionFormat = "csv";
param.vendorExtensions.put(X_COLLECTION_FORMAT, mapCollectionFormat(param.collectionFormat)); param.vendorExtensions.put(X_COLLECTION_FORMAT, mapCollectionFormat(param.collectionFormat)); // TODO: 5.0 Remove
param.vendorExtensions.put(VENDOR_EXTENSION_X_COLLECTION_FORMAT, mapCollectionFormat(param.collectionFormat));
} }
if (!param.required) { if (!param.required) {
op.vendorExtensions.put(X_HAS_OPTIONAL_PARAMS, true); op.vendorExtensions.put(X_HAS_OPTIONAL_PARAMS, true); // TODO: 5.0 Remove
op.vendorExtensions.put(VENDOR_EXTENSION_X_HAS_OPTIONAL_PARAMS, true);
} }
if (typeMapping.containsKey(param.dataType) if (typeMapping.containsKey(param.dataType)
@ -728,7 +774,8 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
String dataType = genEnums && param.isEnum ? param.datatypeWithEnum : param.dataType; String dataType = genEnums && param.isEnum ? param.datatypeWithEnum : param.dataType;
String paramNameType = toDedupedModelName(toTypeName("Param", param.paramName), dataType, !param.isEnum); String paramNameType = toDedupedModelName(toTypeName("Param", param.paramName), dataType, !param.isEnum);
param.vendorExtensions.put(X_PARAM_NAME_TYPE, paramNameType); param.vendorExtensions.put(X_PARAM_NAME_TYPE, paramNameType); // TODO: 5.0 Remove
param.vendorExtensions.put(VENDOR_EXTENSION_X_PARAM_NAME_TYPE, paramNameType);
HashMap<String, Object> props = new HashMap<>(); HashMap<String, Object> props = new HashMap<>();
props.put(X_IS_BODY_PARAM, param.isBodyParam); props.put(X_IS_BODY_PARAM, param.isBodyParam);
@ -791,10 +838,14 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) { public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) {
Map<String, Object> ret = super.postProcessOperationsWithModels(objs, allModels); Map<String, Object> ret = super.postProcessOperationsWithModels(objs, allModels);
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
HashMap<String, Object> pathOps = (HashMap<String, Object>) ret.get("operations"); HashMap<String, Object> pathOps = (HashMap<String, Object>) ret.get("operations");
ArrayList<CodegenOperation> ops = (ArrayList<CodegenOperation>) pathOps.get("operation"); ArrayList<CodegenOperation> ops = (ArrayList<CodegenOperation>) pathOps.get("operation");
if (ops.size() > 0) { if (ops.size() > 0) {
ops.get(0).vendorExtensions.put(X_HAS_NEW_TAG, true); ops.get(0).vendorExtensions.put(X_HAS_NEW_TAG, true); // TODO: 5.0 Remove
ops.get(0).vendorExtensions.put(VENDOR_EXTENSION_X_HAS_NEW_TAG, true);
} }
updateGlobalAdditionalProps(); updateGlobalAdditionalProps();
@ -804,7 +855,10 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
CodegenModel m = (CodegenModel) h.get("model"); CodegenModel m = (CodegenModel) h.get("model");
if (modelMimeTypes.containsKey(m.classname)) { if (modelMimeTypes.containsKey(m.classname)) {
Set<String> mimeTypes = modelMimeTypes.get(m.classname); Set<String> mimeTypes = modelMimeTypes.get(m.classname);
m.vendorExtensions.put(X_MIME_TYPES, mimeTypes);
m.vendorExtensions.put(X_MIME_TYPES, mimeTypes); // TODO: 5.0 Remove
m.vendorExtensions.put(VENDOR_EXTENSION_X_MIME_TYPES, mimeTypes);
if ((boolean) additionalProperties.get(PROP_GENERATE_FORM_URLENCODED_INSTANCES) && mimeTypes.contains("MimeFormUrlEncoded")) { if ((boolean) additionalProperties.get(PROP_GENERATE_FORM_URLENCODED_INSTANCES) && mimeTypes.contains("MimeFormUrlEncoded")) {
Boolean hasMimeFormUrlEncoded = true; Boolean hasMimeFormUrlEncoded = true;
for (CodegenProperty v : m.vars) { for (CodegenProperty v : m.vars) {
@ -813,7 +867,8 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
} }
} }
if (hasMimeFormUrlEncoded) { if (hasMimeFormUrlEncoded) {
m.vendorExtensions.put(X_HAS_MIME_FORM_URL_ENCODED, true); m.vendorExtensions.put(X_HAS_MIME_FORM_URL_ENCODED, true); // TODO: 5.0 Remove
m.vendorExtensions.put(VENDOR_EXTENSION_X_HAS_MIME_FORM_URL_ENCODED, true);
} }
} }
} }
@ -874,9 +929,11 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
if (returnType == null || returnType.equals("null")) { if (returnType == null || returnType.equals("null")) {
if (op.hasProduces) { if (op.hasProduces) {
returnType = "res"; returnType = "res";
op.vendorExtensions.put(X_HAS_UNKNOWN_RETURN, true); op.vendorExtensions.put(X_HAS_UNKNOWN_RETURN, true); // TODO: 5.0 Remove
op.vendorExtensions.put(VENDOR_EXTENSION_X_HAS_UNKNOWN_RETURN, true);
} else { } else {
returnType = "NoContent"; returnType = "NoContent";
// TODO: 5.0 Remove vendor extension usage which is not lower-kebab cased.
if (!op.vendorExtensions.containsKey(X_INLINE_ACCEPT)) { if (!op.vendorExtensions.containsKey(X_INLINE_ACCEPT)) {
SetNoContent(op, X_INLINE_ACCEPT); SetNoContent(op, X_INLINE_ACCEPT);
} }
@ -885,7 +942,8 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
if (returnType.contains(" ")) { if (returnType.contains(" ")) {
returnType = "(" + returnType + ")"; returnType = "(" + returnType + ")";
} }
op.vendorExtensions.put(X_RETURN_TYPE, returnType); op.vendorExtensions.put(X_RETURN_TYPE, returnType); // TODO: 5.0 Remove
op.vendorExtensions.put(VENDOR_EXTENSION_X_RETURN_TYPE, returnType);
} }
private void processProducesConsumes(CodegenOperation op) { private void processProducesConsumes(CodegenOperation op) {
@ -928,14 +986,20 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
private void processInlineConsumesContentType(CodegenOperation op, Map<String, String> m) { private void processInlineConsumesContentType(CodegenOperation op, Map<String, String> m) {
if (op.vendorExtensions.containsKey(X_INLINE_CONTENT_TYPE)) return; if (op.vendorExtensions.containsKey(X_INLINE_CONTENT_TYPE)) return;
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
if ((boolean) additionalProperties.get(PROP_INLINE_MIME_TYPES) if ((boolean) additionalProperties.get(PROP_INLINE_MIME_TYPES)
&& op.consumes.size() == 1 && op.consumes.size() == 1
&& !MIME_ANY.equals(op.consumes.get(0).get(X_MEDIA_DATA_TYPE)) && !MIME_ANY.equals(op.consumes.get(0).get(X_MEDIA_DATA_TYPE))
&& !MIME_NO_CONTENT.equals(op.consumes.get(0).get(X_MEDIA_DATA_TYPE))) { && !MIME_NO_CONTENT.equals(op.consumes.get(0).get(X_MEDIA_DATA_TYPE))) {
op.vendorExtensions.put(X_INLINE_CONTENT_TYPE, m); op.vendorExtensions.put(X_INLINE_CONTENT_TYPE, m); // TODO: 5.0 Remove
op.vendorExtensions.put(VENDOR_EXTENSION_X_INLINE_CONTENT_TYPE, m);
for (CodegenParameter param : op.allParams) { for (CodegenParameter param : op.allParams) {
if (param.isBodyParam && param.required) { if (param.isBodyParam && param.required) {
param.vendorExtensions.put(X_INLINE_CONTENT_TYPE, m); param.vendorExtensions.put(X_INLINE_CONTENT_TYPE, m); // TODO: 5.0 Remove
param.vendorExtensions.put(VENDOR_EXTENSION_X_INLINE_CONTENT_TYPE, m);
} }
} }
} }
@ -946,7 +1010,12 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
&& op.produces.size() == 1 && op.produces.size() == 1
&& !MIME_ANY.equals(op.produces.get(0).get(X_MEDIA_DATA_TYPE)) && !MIME_ANY.equals(op.produces.get(0).get(X_MEDIA_DATA_TYPE))
&& !MIME_NO_CONTENT.equals(op.produces.get(0).get(X_MEDIA_DATA_TYPE))) { && !MIME_NO_CONTENT.equals(op.produces.get(0).get(X_MEDIA_DATA_TYPE))) {
op.vendorExtensions.put(X_INLINE_ACCEPT, m);
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
op.vendorExtensions.put(X_INLINE_ACCEPT, m); // TODO: 5.0 Remove
op.vendorExtensions.put(VENDOR_EXTENSION_X_INLINE_ACCEPT, m);
} }
} }
@ -978,7 +1047,7 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
public Boolean isDuplicate(String paramNameType, String dataType) { public Boolean isDuplicate(String paramNameType, String dataType) {
Map<String, Object> lastParam = this.uniqueParamNameTypes.get(paramNameType); Map<String, Object> lastParam = this.uniqueParamNameTypes.get(paramNameType);
if (lastParam != null) { if (lastParam != null) {
String comparisonKey = lastParam.containsKey(X_ENUM) ? X_ENUM_VALUES : X_DATA_TYPE; String comparisonKey = lastParam.containsKey(VENDOR_EXTENSION_X_ENUM) ? X_ENUM_VALUES : X_DATA_TYPE;
String lastParamDataType = (String) lastParam.get(comparisonKey); String lastParamDataType = (String) lastParam.get(comparisonKey);
if (lastParamDataType != null && lastParamDataType.equals(dataType)) { if (lastParamDataType != null && lastParamDataType.equals(dataType)) {
return true; return true;
@ -1013,7 +1082,7 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
props.put("description", description); props.put("description", description);
} }
props.put(X_ENUM_VALUES, enumValues); props.put(X_ENUM_VALUES, enumValues);
addToUniques(X_ENUM, paramNameType, datatype, props); addToUniques(VENDOR_EXTENSION_X_ENUM, paramNameType, datatype, props);
additionalProperties.put(X_HAS_ENUM_SECTION, true); additionalProperties.put(X_HAS_ENUM_SECTION, true);
} }
@ -1033,7 +1102,7 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
xPath = xPath.replaceAll("^\\[,", "["); xPath = xPath.replaceAll("^\\[,", "[");
xPath = xPath.replaceAll(",\\]$", "]"); xPath = xPath.replaceAll(",\\]$", "]");
} }
op.vendorExtensions.put(X_PATH, xPath); op.vendorExtensions.put(VENDOR_EXTENSION_X_PATH, xPath);
} }
@ -1259,6 +1328,10 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
@Override @Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) { public Map<String, Object> postProcessModels(Map<String, Object> objs) {
List<Object> models = (List<Object>) objs.get("models"); List<Object> models = (List<Object>) objs.get("models");
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
for (Object _mo : models) { for (Object _mo : models) {
Map<String, Object> mo = (Map<String, Object>) _mo; Map<String, Object> mo = (Map<String, Object>) _mo;
CodegenModel cm = (CodegenModel) mo.get("model"); CodegenModel cm = (CodegenModel) mo.get("model");
@ -1268,18 +1341,22 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
if (dataType == null && cm.isArrayModel) { // isAlias + arrayModelType missing "datatype" if (dataType == null && cm.isArrayModel) { // isAlias + arrayModelType missing "datatype"
dataType = "[" + cm.arrayModelType + "]"; dataType = "[" + cm.arrayModelType + "]";
} }
cm.vendorExtensions.put(X_DATA_TYPE, dataType); cm.vendorExtensions.put(X_DATA_TYPE, dataType); // TODO: 5.0 Remove
cm.vendorExtensions.put(VENDOR_EXTENSION_X_DATA_TYPE, dataType);
if (dataType.equals("Maybe A.Value")) { if (dataType.equals("Maybe A.Value")) {
cm.vendorExtensions.put(X_IS_MAYBE_VALUE, true); cm.vendorExtensions.put(X_IS_MAYBE_VALUE, true); // TODO: 5.0 Remove
cm.vendorExtensions.put(VENDOR_EXTENSION_X_IS_MAYBE_VALUE, true);
} }
} }
for (CodegenProperty var : cm.vars) { for (CodegenProperty var : cm.vars) {
String datatype = genEnums && !StringUtils.isBlank(var.datatypeWithEnum) String datatype = genEnums && !StringUtils.isBlank(var.datatypeWithEnum)
? var.datatypeWithEnum ? var.datatypeWithEnum
: var.dataType; : var.dataType;
var.vendorExtensions.put(X_DATA_TYPE, datatype); var.vendorExtensions.put(X_DATA_TYPE, datatype); // TODO: 5.0 Remove
var.vendorExtensions.put(VENDOR_EXTENSION_X_DATA_TYPE, datatype);
if (!var.required && datatype.equals("A.Value") || var.required && datatype.equals("Maybe A.Value")) { if (!var.required && datatype.equals("A.Value") || var.required && datatype.equals("Maybe A.Value")) {
var.vendorExtensions.put(X_IS_MAYBE_VALUE, true); var.vendorExtensions.put(X_IS_MAYBE_VALUE, true); // TODO: 5.0 Remove
var.vendorExtensions.put(VENDOR_EXTENSION_X_IS_MAYBE_VALUE, true);
} }
} }
} }

View File

@ -34,6 +34,7 @@ import java.io.File;
import java.util.*; import java.util.*;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.camelize; import static org.openapitools.codegen.utils.StringUtils.camelize;
public class HaskellServantCodegen extends DefaultCodegen implements CodegenConfig { public class HaskellServantCodegen extends DefaultCodegen implements CodegenConfig {
@ -506,6 +507,9 @@ public class HaskellServantCodegen extends DefaultCodegen implements CodegenConf
public CodegenOperation fromOperation(String resourcePath, String httpMethod, Operation operation, List<Server> servers) { public CodegenOperation fromOperation(String resourcePath, String httpMethod, Operation operation, List<Server> servers) {
CodegenOperation op = super.fromOperation(resourcePath, httpMethod, operation, servers); CodegenOperation op = super.fromOperation(resourcePath, httpMethod, operation, servers);
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
List<String> path = pathToServantRoute(op.path, op.pathParams); List<String> path = pathToServantRoute(op.path, op.pathParams);
List<String> type = pathToClientType(op.path, op.pathParams); List<String> type = pathToClientType(op.path, op.pathParams);
@ -558,7 +562,8 @@ public class HaskellServantCodegen extends DefaultCodegen implements CodegenConf
// store form parameter name in the vendor extensions // store form parameter name in the vendor extensions
for (CodegenParameter param : op.formParams) { for (CodegenParameter param : op.formParams) {
param.vendorExtensions.put("x-formParamName", camelize(param.baseName)); param.vendorExtensions.put("x-formParamName", camelize(param.baseName)); // TODO: 5.0 Remove
param.vendorExtensions.put("x-form-param-name", camelize(param.baseName));
} }
// Add the HTTP method and return type // Add the HTTP method and return type
@ -572,11 +577,15 @@ public class HaskellServantCodegen extends DefaultCodegen implements CodegenConf
path.add("Verb '" + op.httpMethod.toUpperCase(Locale.ROOT) + " 200 '[JSON] " + returnType); path.add("Verb '" + op.httpMethod.toUpperCase(Locale.ROOT) + " 200 '[JSON] " + returnType);
type.add("m " + returnType); type.add("m " + returnType);
op.vendorExtensions.put("x-routeType", joinStrings(" :> ", path)); op.vendorExtensions.put("x-routeType", joinStrings(" :> ", path)); // TODO: 5.0 Remove
op.vendorExtensions.put("x-clientType", joinStrings(" -> ", type)); op.vendorExtensions.put("x-route-type", joinStrings(" :> ", path));
op.vendorExtensions.put("x-formName", "Form" + camelize(op.operationId)); op.vendorExtensions.put("x-clientType", joinStrings(" -> ", type)); // TODO: 5.0 Remove
op.vendorExtensions.put("x-client-type", joinStrings(" -> ", type));
op.vendorExtensions.put("x-formName", "Form" + camelize(op.operationId)); // TODO: 5.0 Remove
op.vendorExtensions.put("x-form-name", "Form" + camelize(op.operationId));
for (CodegenParameter param : op.formParams) { for (CodegenParameter param : op.formParams) {
param.vendorExtensions.put("x-formPrefix", camelize(op.operationId, true)); param.vendorExtensions.put("x-formPrefix", camelize(op.operationId, true)); // TODO: 5.0 Remove
param.vendorExtensions.put("x-form-prefix", camelize(op.operationId, true));
} }
return op; return op;
} }
@ -633,6 +642,9 @@ public class HaskellServantCodegen extends DefaultCodegen implements CodegenConf
public CodegenModel fromModel(String name, Schema mod) { public CodegenModel fromModel(String name, Schema mod) {
CodegenModel model = super.fromModel(name, mod); CodegenModel model = super.fromModel(name, mod);
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
setGenerateToSchema(model); setGenerateToSchema(model);
// Clean up the class name to remove invalid characters // Clean up the class name to remove invalid characters
@ -651,7 +663,9 @@ public class HaskellServantCodegen extends DefaultCodegen implements CodegenConf
String dataOrNewtype = "data"; String dataOrNewtype = "data";
if (!"object".equals(model.dataType) && typeMapping.containsKey(model.dataType)) { if (!"object".equals(model.dataType) && typeMapping.containsKey(model.dataType)) {
String newtype = typeMapping.get(model.dataType); String newtype = typeMapping.get(model.dataType);
model.vendorExtensions.put("x-customNewtype", newtype); model.vendorExtensions.put("x-customNewtype", newtype); // TODO: 5.0 Remove
// note; newtype is a single lowercase word in Haskell (not separated by hyphen)
model.vendorExtensions.put("x-custom-newtype", newtype);
} }
// Provide the prefix as a vendor extension, so that it can be used in the ToJSON and FromJSON instances. // Provide the prefix as a vendor extension, so that it can be used in the ToJSON and FromJSON instances.

View File

@ -46,6 +46,7 @@ import java.util.regex.Pattern;
import static com.google.common.base.CaseFormat.LOWER_CAMEL; import static com.google.common.base.CaseFormat.LOWER_CAMEL;
import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE; import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
import static java.util.Collections.sort; import static java.util.Collections.sort;
import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.camelize; import static org.openapitools.codegen.utils.StringUtils.camelize;
public class JavaClientCodegen extends AbstractJavaCodegen public class JavaClientCodegen extends AbstractJavaCodegen
@ -855,13 +856,18 @@ public class JavaClientCodegen extends AbstractJavaCodegen
public void addOneOfInterfaceModel(ComposedSchema cs, String type) { public void addOneOfInterfaceModel(ComposedSchema cs, String type) {
CodegenModel cm = new CodegenModel(); CodegenModel cm = new CodegenModel();
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
for (Schema o : cs.getOneOf()) { for (Schema o : cs.getOneOf()) {
// TODO: inline objects // TODO: inline objects
cm.oneOf.add(toModelName(ModelUtils.getSimpleRef(o.get$ref()))); cm.oneOf.add(toModelName(ModelUtils.getSimpleRef(o.get$ref())));
} }
cm.name = type; cm.name = type;
cm.classname = type; cm.classname = type;
cm.vendorExtensions.put("isOneOfInterface", true); cm.vendorExtensions.put("isOneOfInterface", true); // TODO: 5.0 Remove
cm.vendorExtensions.put("x-is-one-of-interface", true);
cm.discriminator = createDiscriminator("", (Schema) cs); cm.discriminator = createDiscriminator("", (Schema) cs);
cm.interfaceModels = new ArrayList<CodegenModel>(); cm.interfaceModels = new ArrayList<CodegenModel>();
@ -1011,6 +1017,9 @@ public class JavaClientCodegen extends AbstractJavaCodegen
public Map<String, Object> postProcessAllModels(Map<String, Object> objs) { public Map<String, Object> postProcessAllModels(Map<String, Object> objs) {
objs = super.postProcessAllModels(objs); objs = super.postProcessAllModels(objs);
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
if (this.useOneOfInterfaces) { if (this.useOneOfInterfaces) {
// First, add newly created oneOf interfaces // First, add newly created oneOf interfaces
for (CodegenModel cm : addOneOfInterfaces) { for (CodegenModel cm : addOneOfInterfaces) {
@ -1052,7 +1061,8 @@ public class JavaClientCodegen extends AbstractJavaCodegen
Map<String, Object> mo = (Map<String, Object>) _mo; Map<String, Object> mo = (Map<String, Object>) _mo;
CodegenModel cm = (CodegenModel) mo.get("model"); CodegenModel cm = (CodegenModel) mo.get("model");
if (cm.oneOf.size() > 0) { if (cm.oneOf.size() > 0) {
cm.vendorExtensions.put("isOneOfInterface", true); cm.vendorExtensions.put("isOneOfInterface", true); // TODO: 5.0 Remove
cm.vendorExtensions.put("x-is-one-of-interface", true);
// if this is oneOf interface, make sure we include the necessary jackson imports for it // if this is oneOf interface, make sure we include the necessary jackson imports for it
for (String s : Arrays.asList("JsonTypeInfo", "JsonSubTypes")) { for (String s : Arrays.asList("JsonTypeInfo", "JsonSubTypes")) {
Map<String, String> i = new HashMap<String, String>() {{ Map<String, String> i = new HashMap<String, String>() {{

View File

@ -21,6 +21,8 @@ import io.swagger.v3.oas.models.media.Schema;
import org.openapitools.codegen.*; import org.openapitools.codegen.*;
import org.openapitools.codegen.languages.features.BeanValidationFeatures; import org.openapitools.codegen.languages.features.BeanValidationFeatures;
import org.openapitools.codegen.meta.features.DocumentationFeature; import org.openapitools.codegen.meta.features.DocumentationFeature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.util.List; import java.util.List;
@ -29,10 +31,11 @@ import java.util.Map;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.camelize; import static org.openapitools.codegen.utils.StringUtils.camelize;
public class JavaPlayFrameworkCodegen extends AbstractJavaCodegen implements BeanValidationFeatures { public class JavaPlayFrameworkCodegen extends AbstractJavaCodegen implements BeanValidationFeatures {
private static final Logger LOGGER = LoggerFactory.getLogger(JavaPlayFrameworkCodegen.class);
public static final String TITLE = "title"; public static final String TITLE = "title";
public static final String CONFIG_PACKAGE = "configPackage"; public static final String CONFIG_PACKAGE = "configPackage";
public static final String BASE_PACKAGE = "basePackage"; public static final String BASE_PACKAGE = "basePackage";
@ -289,6 +292,10 @@ public class JavaPlayFrameworkCodegen extends AbstractJavaCodegen implements Bea
@Override @Override
public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) { public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) {
Map<String, Object> operations = (Map<String, Object>) objs.get("operations"); Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
if (operations != null) { if (operations != null) {
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation"); List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
for (CodegenOperation operation : ops) { for (CodegenOperation operation : ops) {
@ -315,10 +322,12 @@ public class JavaPlayFrameworkCodegen extends AbstractJavaCodegen implements Bea
if (operation.returnType != null) { if (operation.returnType != null) {
if (operation.returnType.equals("Boolean")) { if (operation.returnType.equals("Boolean")) {
operation.vendorExtensions.put("missingReturnInfoIfNeeded", "true"); operation.vendorExtensions.put("missingReturnInfoIfNeeded", "true"); // TODO: 5.0 Remove
operation.vendorExtensions.put("x-missing-return-info-if-needed", "true");
} }
if (operation.returnType.equals("BigDecimal")) { if (operation.returnType.equals("BigDecimal")) {
operation.vendorExtensions.put("missingReturnInfoIfNeeded", "1.0"); operation.vendorExtensions.put("missingReturnInfoIfNeeded", "1.0"); // TODO: 5.0 Remove
operation.vendorExtensions.put("x-missing-return-info-if-needed", "1.0");
} }
if (operation.returnType.startsWith("List")) { if (operation.returnType.startsWith("List")) {
String rt = operation.returnType; String rt = operation.returnType;

View File

@ -33,6 +33,7 @@ import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.util.*; import java.util.*;
import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.*; import static org.openapitools.codegen.utils.StringUtils.*;
public class JavascriptClientCodegen extends DefaultCodegen implements CodegenConfig { public class JavascriptClientCodegen extends DefaultCodegen implements CodegenConfig {
@ -860,6 +861,10 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
@Override @Override
public CodegenModel fromModel(String name, Schema model) { public CodegenModel fromModel(String name, Schema model) {
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
Map<String, Schema> allDefinitions = ModelUtils.getSchemas(this.openAPI); Map<String, Schema> allDefinitions = ModelUtils.getSchemas(this.openAPI);
CodegenModel codegenModel = super.fromModel(name, model); CodegenModel codegenModel = super.fromModel(name, model);
@ -871,17 +876,24 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
if (ModelUtils.isArraySchema(model)) { if (ModelUtils.isArraySchema(model)) {
ArraySchema am = (ArraySchema) model; ArraySchema am = (ArraySchema) model;
if (codegenModel != null && am.getItems() != null) { if (codegenModel != null && am.getItems() != null) {
codegenModel.getVendorExtensions().put("x-isArray", true); String itemType = getSchemaType(am.getItems());
codegenModel.getVendorExtensions().put("x-itemType", getSchemaType(am.getItems())); codegenModel.vendorExtensions.put("x-isArray", true); // TODO: 5.0 Remove
codegenModel.vendorExtensions.put("x-is-array", true);
codegenModel.vendorExtensions.put("x-itemType", itemType); // TODO: 5.0 Remove
codegenModel.vendorExtensions.put("x-item-type", itemType);
} }
} else if (ModelUtils.isMapSchema(model)) { } else if (ModelUtils.isMapSchema(model)) {
if (codegenModel != null && ModelUtils.getAdditionalProperties(model) != null) { if (codegenModel != null && ModelUtils.getAdditionalProperties(model) != null) {
codegenModel.getVendorExtensions().put("x-isMap", true); String itemType = getSchemaType(ModelUtils.getAdditionalProperties(model));
codegenModel.getVendorExtensions().put("x-itemType", getSchemaType(ModelUtils.getAdditionalProperties(model))); codegenModel.vendorExtensions.put("x-isMap", true); // TODO: 5.0 Remove
codegenModel.vendorExtensions.put("x-is-map", true);
codegenModel.vendorExtensions.put("x-itemType",itemType); // TODO: 5.0 Remove
codegenModel.vendorExtensions.put("x-item-type",itemType);
} else { } else {
String type = model.getType(); String type = model.getType();
if (codegenModel != null && isPrimitiveType(type)) { if (codegenModel != null && isPrimitiveType(type)) {
codegenModel.vendorExtensions.put("x-isPrimitive", true); codegenModel.vendorExtensions.put("x-isPrimitive", true); // TODO: 5.0 Remove
codegenModel.vendorExtensions.put("x-is-primitive", true);
} }
} }
} }
@ -979,6 +991,10 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
// Generate and store argument list string of each operation into // Generate and store argument list string of each operation into
// vendor-extension: x-codegen-argList. // vendor-extension: x-codegen-argList.
Map<String, Object> operations = (Map<String, Object>) objs.get("operations"); Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
if (operations != null) { if (operations != null) {
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation"); List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
for (CodegenOperation operation : ops) { for (CodegenOperation operation : ops) {
@ -1004,8 +1020,11 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
if (!usePromises) { if (!usePromises) {
argList.add("callback"); argList.add("callback");
} }
operation.vendorExtensions.put("x-codegen-argList", StringUtils.join(argList, ", ")); String joinedArgList = StringUtils.join(argList, ", ");
operation.vendorExtensions.put("x-codegen-hasOptionalParams", hasOptionalParams); operation.vendorExtensions.put("x-codegen-argList", joinedArgList); // TODO: 5.0 Remove
operation.vendorExtensions.put("x-codegen-arg-list", joinedArgList);
operation.vendorExtensions.put("x-codegen-hasOptionalParams", hasOptionalParams); // TODO: 5.0 Remove
operation.vendorExtensions.put("x-codegen-has-optional-params", hasOptionalParams);
// Store JSDoc type specification into vendor-extension: x-jsdoc-type. // Store JSDoc type specification into vendor-extension: x-jsdoc-type.
for (CodegenParameter cp : operation.allParams) { for (CodegenParameter cp : operation.allParams) {
@ -1029,6 +1048,10 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
public Map<String, Object> postProcessModels(Map<String, Object> objs) { public Map<String, Object> postProcessModels(Map<String, Object> objs) {
objs = super.postProcessModelsEnum(objs); objs = super.postProcessModelsEnum(objs);
List<Object> models = (List<Object>) objs.get("models"); List<Object> models = (List<Object>) objs.get("models");
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
for (Object _mo : models) { for (Object _mo : models) {
Map<String, Object> mo = (Map<String, Object>) _mo; Map<String, Object> mo = (Map<String, Object>) _mo;
CodegenModel cm = (CodegenModel) mo.get("model"); CodegenModel cm = (CodegenModel) mo.get("model");
@ -1079,9 +1102,11 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
for (CodegenProperty var : cm.vars) { for (CodegenProperty var : cm.vars) {
Optional.ofNullable(lastRequired).ifPresent(_lastRequired -> { Optional.ofNullable(lastRequired).ifPresent(_lastRequired -> {
if (var == _lastRequired) { if (var == _lastRequired) {
var.vendorExtensions.put("x-codegen-hasMoreRequired", false); var.vendorExtensions.put("x-codegen-hasMoreRequired", false); // TODO: 5.0 Remove
var.vendorExtensions.put("x-codegen-has-more-required", false);
} else if (var.required) { } else if (var.required) {
var.vendorExtensions.put("x-codegen-hasMoreRequired", true); var.vendorExtensions.put("x-codegen-hasMoreRequired", true); // TODO: 5.0 Remove
var.vendorExtensions.put("x-codegen-has-more-required", true);
} }
}); });
} }

View File

@ -30,7 +30,8 @@ import static org.openapitools.codegen.utils.StringUtils.underscore;
public class MysqlSchemaCodegen extends DefaultCodegen implements CodegenConfig { public class MysqlSchemaCodegen extends DefaultCodegen implements CodegenConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(MysqlSchemaCodegen.class); private static final Logger LOGGER = LoggerFactory.getLogger(MysqlSchemaCodegen.class);
public static final String CODEGEN_VENDOR_EXTENSION_KEY = "x-mysqlSchema"; public static final String CODEGEN_VENDOR_EXTENSION_KEY = "x-mysqlSchema"; // TODO: 5.0 Remove
public static final String VENDOR_EXTENSION_MYSQL_SCHEMA = "x-mysql-schema";
public static final String DEFAULT_DATABASE_NAME = "defaultDatabaseName"; public static final String DEFAULT_DATABASE_NAME = "defaultDatabaseName";
public static final String JSON_DATA_TYPE_ENABLED = "jsonDataTypeEnabled"; public static final String JSON_DATA_TYPE_ENABLED = "jsonDataTypeEnabled";
public static final String IDENTIFIER_NAMING_CONVENTION = "identifierNamingConvention"; public static final String IDENTIFIER_NAMING_CONVENTION = "identifierNamingConvention";
@ -338,7 +339,8 @@ public class MysqlSchemaCodegen extends DefaultCodegen implements CodegenConfig
description = (description == null || description.isEmpty()) ? commentExtra : description + ". " + commentExtra; description = (description == null || description.isEmpty()) ? commentExtra : description + ". " + commentExtra;
} }
vendorExtensions.put(CODEGEN_VENDOR_EXTENSION_KEY, mysqlSchema); vendorExtensions.put(CODEGEN_VENDOR_EXTENSION_KEY, mysqlSchema); // TODO: 5.0 Remove
vendorExtensions.put(VENDOR_EXTENSION_MYSQL_SCHEMA, mysqlSchema);
mysqlSchema.put("columnDefinition", columnDefinition); mysqlSchema.put("columnDefinition", columnDefinition);
columnDefinition.put("colName", colName); columnDefinition.put("colName", colName);
@ -425,7 +427,8 @@ public class MysqlSchemaCodegen extends DefaultCodegen implements CodegenConfig
description = (description == null || description.isEmpty()) ? commentExtra : description + ". " + commentExtra; description = (description == null || description.isEmpty()) ? commentExtra : description + ". " + commentExtra;
} }
vendorExtensions.put(CODEGEN_VENDOR_EXTENSION_KEY, mysqlSchema); vendorExtensions.put(CODEGEN_VENDOR_EXTENSION_KEY, mysqlSchema); // TODO: 5.0 Remove
vendorExtensions.put(VENDOR_EXTENSION_MYSQL_SCHEMA, mysqlSchema);
mysqlSchema.put("columnDefinition", columnDefinition); mysqlSchema.put("columnDefinition", columnDefinition);
columnDefinition.put("colName", colName); columnDefinition.put("colName", colName);
@ -503,7 +506,8 @@ public class MysqlSchemaCodegen extends DefaultCodegen implements CodegenConfig
description = (description == null || description.isEmpty()) ? commentExtra : description + ". " + commentExtra; description = (description == null || description.isEmpty()) ? commentExtra : description + ". " + commentExtra;
} }
vendorExtensions.put(CODEGEN_VENDOR_EXTENSION_KEY, mysqlSchema); vendorExtensions.put(CODEGEN_VENDOR_EXTENSION_KEY, mysqlSchema); // TODO: 5.0 Remove
vendorExtensions.put(VENDOR_EXTENSION_MYSQL_SCHEMA, mysqlSchema);
mysqlSchema.put("columnDefinition", columnDefinition); mysqlSchema.put("columnDefinition", columnDefinition);
columnDefinition.put("colName", colName); columnDefinition.put("colName", colName);
columnDefinition.put("colDataType", "TINYINT"); columnDefinition.put("colDataType", "TINYINT");
@ -561,7 +565,8 @@ public class MysqlSchemaCodegen extends DefaultCodegen implements CodegenConfig
description = (description == null || description.isEmpty()) ? commentExtra : description + ". " + commentExtra; description = (description == null || description.isEmpty()) ? commentExtra : description + ". " + commentExtra;
} }
vendorExtensions.put(CODEGEN_VENDOR_EXTENSION_KEY, mysqlSchema); vendorExtensions.put(CODEGEN_VENDOR_EXTENSION_KEY, mysqlSchema); // TODO: 5.0 Remove
vendorExtensions.put(VENDOR_EXTENSION_MYSQL_SCHEMA, mysqlSchema);
mysqlSchema.put("columnDefinition", columnDefinition); mysqlSchema.put("columnDefinition", columnDefinition);
columnDefinition.put("colName", colName); columnDefinition.put("colName", colName);
@ -635,7 +640,8 @@ public class MysqlSchemaCodegen extends DefaultCodegen implements CodegenConfig
description = (description == null || description.isEmpty()) ? commentExtra : description + ". " + commentExtra; description = (description == null || description.isEmpty()) ? commentExtra : description + ". " + commentExtra;
} }
vendorExtensions.put(CODEGEN_VENDOR_EXTENSION_KEY, mysqlSchema); vendorExtensions.put(CODEGEN_VENDOR_EXTENSION_KEY, mysqlSchema); // TODO: 5.0 Remove
vendorExtensions.put(VENDOR_EXTENSION_MYSQL_SCHEMA, mysqlSchema);
mysqlSchema.put("columnDefinition", columnDefinition); mysqlSchema.put("columnDefinition", columnDefinition);
columnDefinition.put("colName", colName); columnDefinition.put("colName", colName);
columnDefinition.put("colDataType", dataType); columnDefinition.put("colDataType", dataType);
@ -686,7 +692,8 @@ public class MysqlSchemaCodegen extends DefaultCodegen implements CodegenConfig
description = (description == null || description.isEmpty()) ? commentExtra : description + ". " + commentExtra; description = (description == null || description.isEmpty()) ? commentExtra : description + ". " + commentExtra;
} }
vendorExtensions.put(CODEGEN_VENDOR_EXTENSION_KEY, mysqlSchema); vendorExtensions.put(CODEGEN_VENDOR_EXTENSION_KEY, mysqlSchema); // TODO: 5.0 Remove
vendorExtensions.put(VENDOR_EXTENSION_MYSQL_SCHEMA, mysqlSchema);
mysqlSchema.put("columnDefinition", columnDefinition); mysqlSchema.put("columnDefinition", columnDefinition);
columnDefinition.put("colName", colName); columnDefinition.put("colName", colName);
columnDefinition.put("colDataType", dataType); columnDefinition.put("colDataType", dataType);
@ -740,7 +747,8 @@ public class MysqlSchemaCodegen extends DefaultCodegen implements CodegenConfig
description = (description == null || description.isEmpty()) ? commentExtra : description + ". " + commentExtra; description = (description == null || description.isEmpty()) ? commentExtra : description + ". " + commentExtra;
} }
vendorExtensions.put(CODEGEN_VENDOR_EXTENSION_KEY, mysqlSchema); vendorExtensions.put(CODEGEN_VENDOR_EXTENSION_KEY, mysqlSchema); // TODO: 5.0 Remove
vendorExtensions.put(VENDOR_EXTENSION_MYSQL_SCHEMA, mysqlSchema);
mysqlSchema.put("columnDefinition", columnDefinition); mysqlSchema.put("columnDefinition", columnDefinition);
columnDefinition.put("colName", colName); columnDefinition.put("colName", colName);
columnDefinition.put("colDataType", "TEXT"); columnDefinition.put("colDataType", "TEXT");

View File

@ -35,6 +35,7 @@ import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.apache.commons.lang3.StringUtils.capitalize; import static org.apache.commons.lang3.StringUtils.capitalize;
import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.camelize; import static org.openapitools.codegen.utils.StringUtils.camelize;
import static org.openapitools.codegen.utils.StringUtils.escape; import static org.openapitools.codegen.utils.StringUtils.escape;
import static org.openapitools.codegen.utils.StringUtils.underscore; import static org.openapitools.codegen.utils.StringUtils.underscore;
@ -713,6 +714,10 @@ public class OCamlClientCodegen extends DefaultCodegen implements CodegenConfig
Map<String, Object> objectMap = (Map<String, Object>) objs.get("operations"); Map<String, Object> objectMap = (Map<String, Object>) objs.get("operations");
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
List<CodegenOperation> operations = (List<CodegenOperation>) objectMap.get("operation"); List<CodegenOperation> operations = (List<CodegenOperation>) objectMap.get("operation");
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
for (CodegenOperation operation : operations) { for (CodegenOperation operation : operations) {
// http method verb conversion, depending on client library (e.g. Hyper: PUT => Put, Reqwest: PUT => put) // http method verb conversion, depending on client library (e.g. Hyper: PUT => Put, Reqwest: PUT => put)
//if (CO_HTTP.equals(getLibrary())) { //if (CO_HTTP.equals(getLibrary())) {
@ -723,7 +728,8 @@ public class OCamlClientCodegen extends DefaultCodegen implements CodegenConfig
} }
if ("Yojson.Safe.t".equals(operation.returnBaseType)) { if ("Yojson.Safe.t".equals(operation.returnBaseType)) {
operation.vendorExtensions.put("x-returnFreeFormObject", true); operation.vendorExtensions.put("x-returnFreeFormObject", true); // TODO: 5.0 Remove
operation.vendorExtensions.put("x-return-free-form-object", true);
} }
} }

View File

@ -29,6 +29,7 @@ import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.util.*; import java.util.*;
import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.camelize; import static org.openapitools.codegen.utils.StringUtils.camelize;
public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig { public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
@ -652,12 +653,17 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override @Override
public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) { public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) {
Map<String, Object> operations = (Map<String, Object>) objs.get("operations"); Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
if (operations != null) { if (operations != null) {
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation"); List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
for (CodegenOperation operation : ops) { for (CodegenOperation operation : ops) {
if (!operation.allParams.isEmpty()) { if (!operation.allParams.isEmpty()) {
String firstParamName = operation.allParams.get(0).paramName; String firstParamName = operation.allParams.get(0).paramName;
operation.vendorExtensions.put("firstParamAltName", camelize(firstParamName)); operation.vendorExtensions.put("firstParamAltName", camelize(firstParamName)); // TODO: 5.0 Remove
operation.vendorExtensions.put("x-first-param-alt-name", camelize(firstParamName));
} }
} }
} }
@ -667,7 +673,12 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
@Override @Override
public void postProcessModelProperty(CodegenModel model, CodegenProperty schema) { public void postProcessModelProperty(CodegenModel model, CodegenProperty schema) {
super.postProcessModelProperty(model, schema); super.postProcessModelProperty(model, schema);
schema.vendorExtensions.put("x-uppercaseName", camelize(schema.name));
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
schema.vendorExtensions.put("x-uppercaseName", camelize(schema.name)); // TODO: 5.0 Remove
schema.vendorExtensions.put("x-uppercase-name", camelize(schema.name));
} }
/** /**

View File

@ -29,6 +29,7 @@ import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.util.*; import java.util.*;
import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.camelize; import static org.openapitools.codegen.utils.StringUtils.camelize;
public class PhpSymfonyServerCodegen extends AbstractPhpCodegen implements CodegenConfig { public class PhpSymfonyServerCodegen extends AbstractPhpCodegen implements CodegenConfig {
@ -382,6 +383,9 @@ public class PhpSymfonyServerCodegen extends AbstractPhpCodegen implements Codeg
public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) { public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) {
objs = super.postProcessOperationsWithModels(objs, allModels); objs = super.postProcessOperationsWithModels(objs, allModels);
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
Map<String, Object> operations = (Map<String, Object>) objs.get("operations"); Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
operations.put("controllerName", toControllerName((String) operations.get("pathPrefix"))); operations.put("controllerName", toControllerName((String) operations.get("pathPrefix")));
operations.put("symfonyService", toSymfonyService((String) operations.get("pathPrefix"))); operations.put("symfonyService", toSymfonyService((String) operations.get("pathPrefix")));
@ -397,17 +401,21 @@ public class PhpSymfonyServerCodegen extends AbstractPhpCodegen implements Codeg
// to the templating engine // to the templating engine
String typeHint = getTypeHint(param.dataType); String typeHint = getTypeHint(param.dataType);
if (!typeHint.isEmpty()) { if (!typeHint.isEmpty()) {
param.vendorExtensions.put("x-parameterType", typeHint); param.vendorExtensions.put("x-parameterType", typeHint); // TODO: 5.0 Remove
param.vendorExtensions.put("x-parameter-type", typeHint);
} }
if (param.isContainer) { if (param.isContainer) {
param.vendorExtensions.put("x-parameterType", getTypeHint(param.dataType + "[]")); param.vendorExtensions.put("x-parameterType", getTypeHint(param.dataType + "[]")); // TODO: 5.0 Remove
param.vendorExtensions.put("x-parameter-type", getTypeHint(param.dataType + "[]"));
} }
// Create a variable to display the correct data type in comments for interfaces // Create a variable to display the correct data type in comments for interfaces
param.vendorExtensions.put("x-commentType", param.dataType); param.vendorExtensions.put("x-commentType", param.dataType); // TODO: 5.0 Remove
param.vendorExtensions.put("x-comment-type", param.dataType);
if (param.isContainer) { if (param.isContainer) {
param.vendorExtensions.put("x-commentType", param.dataType + "[]"); param.vendorExtensions.put("x-commentType", param.dataType + "[]"); // TODO: 5.0 Remove
param.vendorExtensions.put("x-comment-type", param.dataType + "[]");
} }
// Quote default values for strings // Quote default values for strings
@ -421,12 +429,15 @@ public class PhpSymfonyServerCodegen extends AbstractPhpCodegen implements Codeg
// Create a variable to display the correct return type in comments for interfaces // Create a variable to display the correct return type in comments for interfaces
if (op.returnType != null) { if (op.returnType != null) {
op.vendorExtensions.put("x-commentType", op.returnType); op.vendorExtensions.put("x-commentType", op.returnType); // TODO: 5.0 Remove
op.vendorExtensions.put("x-comment-type", op.returnType);
if (op.returnContainer != null && op.returnContainer.equals("array")) { if (op.returnContainer != null && op.returnContainer.equals("array")) {
op.vendorExtensions.put("x-commentType", op.returnType + "[]"); op.vendorExtensions.put("x-commentType", op.returnType + "[]"); // TODO: 5.0 Remove
op.vendorExtensions.put("x-comment-type", op.returnType + "[]");
} }
} else { } else {
op.vendorExtensions.put("x-commentType", "void"); op.vendorExtensions.put("x-commentType", "void"); // TODO: 5.0 Remove
op.vendorExtensions.put("x-comment-type", "void");
} }
// Add operation's authentication methods to whole interface // Add operation's authentication methods to whole interface
@ -448,6 +459,9 @@ public class PhpSymfonyServerCodegen extends AbstractPhpCodegen implements Codeg
public Map<String, Object> postProcessModels(Map<String, Object> objs) { public Map<String, Object> postProcessModels(Map<String, Object> objs) {
objs = super.postProcessModels(objs); objs = super.postProcessModels(objs);
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
ArrayList<Object> modelsArray = (ArrayList<Object>) objs.get("models"); ArrayList<Object> modelsArray = (ArrayList<Object>) objs.get("models");
Map<String, Object> models = (Map<String, Object>) modelsArray.get(0); Map<String, Object> models = (Map<String, Object>) modelsArray.get(0);
CodegenModel model = (CodegenModel) models.get("model"); CodegenModel model = (CodegenModel) models.get("model");
@ -459,17 +473,21 @@ public class PhpSymfonyServerCodegen extends AbstractPhpCodegen implements Codeg
// to the templating engine // to the templating engine
String typeHint = getTypeHint(var.dataType); String typeHint = getTypeHint(var.dataType);
if (!typeHint.isEmpty()) { if (!typeHint.isEmpty()) {
var.vendorExtensions.put("x-parameterType", typeHint); var.vendorExtensions.put("x-parameterType", typeHint); // TODO: 5.0 Remove
var.vendorExtensions.put("x-parameter-type", typeHint);
} }
if (var.isContainer) { if (var.isContainer) {
var.vendorExtensions.put("x-parameterType", getTypeHint(var.dataType + "[]")); var.vendorExtensions.put("x-parameterType", getTypeHint(var.dataType + "[]")); // TODO: 5.0 Remove
var.vendorExtensions.put("x-parameter-type", getTypeHint(var.dataType + "[]"));
} }
// Create a variable to display the correct data type in comments for models // Create a variable to display the correct data type in comments for models
var.vendorExtensions.put("x-commentType", var.dataType); var.vendorExtensions.put("x-commentType", var.dataType); // TODO: 5.0 Remove
var.vendorExtensions.put("x-comment-type", var.dataType);
if (var.isContainer) { if (var.isContainer) {
var.vendorExtensions.put("x-commentType", var.dataType + "[]"); var.vendorExtensions.put("x-commentType", var.dataType + "[]"); // TODO: 5.0 Remove
var.vendorExtensions.put("x-comment-type", var.dataType + "[]");
} }
} }
} }

View File

@ -31,6 +31,7 @@ import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.util.*; import java.util.*;
import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.camelize; import static org.openapitools.codegen.utils.StringUtils.camelize;
import static org.openapitools.codegen.utils.StringUtils.underscore; import static org.openapitools.codegen.utils.StringUtils.underscore;
@ -188,6 +189,10 @@ public class RustClientCodegen extends DefaultCodegen implements CodegenConfig {
public Map<String, Object> postProcessAllModels(Map<String, Object> objs) { public Map<String, Object> postProcessAllModels(Map<String, Object> objs) {
// Index all CodegenModels by model name. // Index all CodegenModels by model name.
Map<String, CodegenModel> allModels = new HashMap<>(); Map<String, CodegenModel> allModels = new HashMap<>();
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
for (Map.Entry<String, Object> entry : objs.entrySet()) { for (Map.Entry<String, Object> entry : objs.entrySet()) {
String modelName = toModelName(entry.getKey()); String modelName = toModelName(entry.getKey());
Map<String, Object> inner = (Map<String, Object>) entry.getValue(); Map<String, Object> inner = (Map<String, Object>) entry.getValue();
@ -215,8 +220,11 @@ public class RustClientCodegen extends DefaultCodegen implements CodegenConfig {
discriminatorVars.add(mas); discriminatorVars.add(mas);
} }
// TODO: figure out how to properly have the original property type that didn't go through toVarName // TODO: figure out how to properly have the original property type that didn't go through toVarName
cm.vendorExtensions.put("tagName", cm.discriminator.getPropertyName().replace("_", "")); String vendorExtensionTagName = cm.discriminator.getPropertyName().replace("_", "");
cm.vendorExtensions.put("mappedModels", discriminatorVars); cm.vendorExtensions.put("tagName", vendorExtensionTagName); // TODO: 5.0 Remove
cm.vendorExtensions.put("x-tag-name", vendorExtensionTagName);
cm.vendorExtensions.put("mappedModels", discriminatorVars); // TODO: 5.0 Remove
cm.vendorExtensions.put("x-mapped-models", discriminatorVars);
} }
} }
} }

View File

@ -41,6 +41,7 @@ import java.net.URL;
import java.util.*; import java.util.*;
import java.util.Map.Entry; import java.util.Map.Entry;
import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.camelize; import static org.openapitools.codegen.utils.StringUtils.camelize;
import static org.openapitools.codegen.utils.StringUtils.underscore; import static org.openapitools.codegen.utils.StringUtils.underscore;
@ -552,6 +553,9 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
Map<String, Schema> definitions = ModelUtils.getSchemas(this.openAPI); Map<String, Schema> definitions = ModelUtils.getSchemas(this.openAPI);
CodegenOperation op = super.fromOperation(path, httpMethod, operation, servers); CodegenOperation op = super.fromOperation(path, httpMethod, operation, servers);
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
String pathFormatString = op.path; String pathFormatString = op.path;
for (CodegenParameter param : op.pathParams) { for (CodegenParameter param : op.pathParams) {
// Replace {baseName} with {paramName} for format string // Replace {baseName} with {paramName} for format string
@ -606,12 +610,23 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
pathSetEntry.put("pathRegEx", pathRegEx + "$"); pathSetEntry.put("pathRegEx", pathRegEx + "$");
pathSetMap.put(pathId, pathSetEntry); pathSetMap.put(pathId, pathSetEntry);
} }
op.vendorExtensions.put("operation_id", underscore(op.operationId)); String underscoredOperationId = underscore(op.operationId);
op.vendorExtensions.put("uppercase_operation_id", underscore(op.operationId).toUpperCase(Locale.ROOT)); op.vendorExtensions.put("operation_id", underscoredOperationId); // TODO: 5.0 Remove
op.vendorExtensions.put("path", op.path.replace("{", ":").replace("}", "")); op.vendorExtensions.put("x-operation-id", underscoredOperationId);
op.vendorExtensions.put("PATH_ID", pathId); op.vendorExtensions.put("uppercase_operation_id", underscoredOperationId.toUpperCase(Locale.ROOT)); // TODO: 5.0 Remove
op.vendorExtensions.put("hasPathParams", !op.pathParams.isEmpty()); op.vendorExtensions.put("x-uppercase-operation-id", underscoredOperationId.toUpperCase(Locale.ROOT));
op.vendorExtensions.put("HttpMethod", Character.toUpperCase(op.httpMethod.charAt(0)) + op.httpMethod.substring(1).toLowerCase(Locale.ROOT)); String vendorExtensionPath = op.path.replace("{", ":").replace("}", "");
op.vendorExtensions.put("path", vendorExtensionPath); // TODO: 5.0 Remove
op.vendorExtensions.put("x-path",vendorExtensionPath);
op.vendorExtensions.put("PATH_ID", pathId); // TODO: 5.0 Remove
op.vendorExtensions.put("x-path-id", pathId);
op.vendorExtensions.put("hasPathParams", !op.pathParams.isEmpty()); // TODO: 5.0 Remove
op.vendorExtensions.put("x-has-path-params", !op.pathParams.isEmpty());
String vendorExtensionHttpMethod = Character.toUpperCase(op.httpMethod.charAt(0)) + op.httpMethod.substring(1).toLowerCase(Locale.ROOT);
op.vendorExtensions.put("HttpMethod", vendorExtensionHttpMethod); // TODO: 5.0 Remove
op.vendorExtensions.put("x-http-method", vendorExtensionHttpMethod);
for (CodegenParameter param : op.allParams) { for (CodegenParameter param : op.allParams) {
processParam(param, op); processParam(param, op);
} }
@ -653,7 +668,8 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
processParam(param, op); processParam(param, op);
// Give header params a name in camel case. CodegenParameters don't have a nameInCamelCase property. // Give header params a name in camel case. CodegenParameters don't have a nameInCamelCase property.
param.vendorExtensions.put("typeName", toModelName(param.baseName)); param.vendorExtensions.put("typeName", toModelName(param.baseName)); // TODO: 5.0 Remove
param.vendorExtensions.put("x-type-name", toModelName(param.baseName));
} }
// Set for deduplication of response IDs // Set for deduplication of response IDs
@ -701,11 +717,17 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
responseIds.add(responseId); responseIds.add(responseId);
rsp.vendorExtensions.put("x-responseId", responseId); String underscoredResponseId = underscore(responseId).toUpperCase(Locale.ROOT);
rsp.vendorExtensions.put("x-uppercaseResponseId", underscore(responseId).toUpperCase(Locale.ROOT)); rsp.vendorExtensions.put("x-responseId", responseId); // TODO: 5.0 Remove
rsp.vendorExtensions.put("uppercase_operation_id", underscore(op.operationId).toUpperCase(Locale.ROOT)); rsp.vendorExtensions.put("x-response-id", responseId);
rsp.vendorExtensions.put("x-uppercaseResponseId", underscoredResponseId.toUpperCase(Locale.ROOT)); // TODO: 5.0 Remove
rsp.vendorExtensions.put("x-uppercase-response-id", underscoredResponseId.toUpperCase(Locale.ROOT));
rsp.vendorExtensions.put("uppercase_operation_id", underscoredOperationId.toUpperCase(Locale.ROOT)); // TODO: 5.0 Remove
rsp.vendorExtensions.put("x-uppercase-operation-id", underscoredOperationId.toUpperCase(Locale.ROOT));
if (rsp.dataType != null) { if (rsp.dataType != null) {
rsp.vendorExtensions.put("uppercase_data_type", (rsp.dataType.replace("models::", "")).toUpperCase(Locale.ROOT)); String uppercaseDataType = (rsp.dataType.replace("models::", "")).toUpperCase(Locale.ROOT);
rsp.vendorExtensions.put("uppercase_data_type", uppercaseDataType); // TODO: 5.0 Remove
rsp.vendorExtensions.put("x-uppercase-data-type", uppercaseDataType);
// Get the mimetype which is produced by this response. Note // Get the mimetype which is produced by this response. Note
// that although in general responses produces a set of // that although in general responses produces a set of
@ -754,12 +776,14 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
outputMime = firstProduces; outputMime = firstProduces;
} }
rsp.vendorExtensions.put("mimeType", outputMime); rsp.vendorExtensions.put("mimeType", outputMime); // TODO: 5.0 Remove
rsp.vendorExtensions.put("x-mime-type", outputMime);
// Write out the type of data we actually expect this response // Write out the type of data we actually expect this response
// to make. // to make.
if (producesXml) { if (producesXml) {
rsp.vendorExtensions.put("producesXml", true); rsp.vendorExtensions.put("producesXml", true); // TODO: 5.0 Remove
rsp.vendorExtensions.put("x-produces-xml", true);
} else if (producesPlainText) { } else if (producesPlainText) {
// Plain text means that there is not structured data in // Plain text means that there is not structured data in
// this response. So it'll either be a UTF-8 encoded string // this response. So it'll either be a UTF-8 encoded string
@ -770,12 +794,15 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
// base64 encoding should be done. They both look like // base64 encoding should be done. They both look like
// 'producesBytes'. // 'producesBytes'.
if (rsp.dataType.equals(bytesType)) { if (rsp.dataType.equals(bytesType)) {
rsp.vendorExtensions.put("producesBytes", true); rsp.vendorExtensions.put("producesBytes", true); // TODO: 5.0 Remove
rsp.vendorExtensions.put("x-produces-bytes", true);
} else { } else {
rsp.vendorExtensions.put("producesPlainText", true); rsp.vendorExtensions.put("producesPlainText", true); // TODO: 5.0 Remove
rsp.vendorExtensions.put("x-produces-plain-text", true);
} }
} else { } else {
rsp.vendorExtensions.put("producesJson", true); rsp.vendorExtensions.put("producesJson", true); // TODO: 5.0 Remove
rsp.vendorExtensions.put("x-produces-json", true);
// If the data type is just "object", then ensure that the // If the data type is just "object", then ensure that the
// Rust data type is "serde_json::Value". This allows us // Rust data type is "serde_json::Value". This allows us
// to define APIs that can return arbitrary JSON bodies. // to define APIs that can return arbitrary JSON bodies.
@ -791,7 +818,8 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
if ((model != null)) { if ((model != null)) {
XML xml = model.getXml(); XML xml = model.getXml();
if ((xml != null) && (xml.getNamespace() != null)) { if ((xml != null) && (xml.getNamespace() != null)) {
rsp.vendorExtensions.put("has_namespace", "true"); rsp.vendorExtensions.put("has_namespace", "true"); // TODO: 5.0 Remove
rsp.vendorExtensions.put("x-has-namespace", "true");
} }
} }
} }
@ -818,6 +846,9 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
Map<String, Object> operations = (Map<String, Object>) objs.get("operations"); Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation"); List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
for (CodegenOperation op : operationList) { for (CodegenOperation op : operationList) {
boolean consumesPlainText = false; boolean consumesPlainText = false;
boolean consumesXml = false; boolean consumesXml = false;
@ -835,37 +866,47 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
} else if (isMimetypeWwwFormUrlEncoded(mediaType)) { } else if (isMimetypeWwwFormUrlEncoded(mediaType)) {
additionalProperties.put("usesUrlEncodedForm", true); additionalProperties.put("usesUrlEncodedForm", true);
} else if (isMimetypeMultipartFormData(mediaType)) { } else if (isMimetypeMultipartFormData(mediaType)) {
op.vendorExtensions.put("consumesMultipart", true); op.vendorExtensions.put("consumesMultipart", true); // TODO: 5.0 Remove
op.vendorExtensions.put("x-consumes-multipart", true);
additionalProperties.put("apiUsesMultipart", true); additionalProperties.put("apiUsesMultipart", true);
} }
} }
} }
} }
String underscoredOperationId = underscore(op.operationId).toUpperCase(Locale.ROOT);
if (op.bodyParam != null) { if (op.bodyParam != null) {
// Default to consuming json // Default to consuming json
op.bodyParam.vendorExtensions.put("uppercase_operation_id", underscore(op.operationId).toUpperCase(Locale.ROOT)); op.bodyParam.vendorExtensions.put("uppercase_operation_id", underscoredOperationId); // TODO: 5.0 Remove
op.bodyParam.vendorExtensions.put("x-uppercase-operation-id", underscoredOperationId);
if (consumesXml) { if (consumesXml) {
op.bodyParam.vendorExtensions.put("consumesXml", true); op.bodyParam.vendorExtensions.put("consumesXml", true); // TODO: 5.0 Remove
op.bodyParam.vendorExtensions.put("x-consumes-xml", true);
} else if (consumesPlainText) { } else if (consumesPlainText) {
op.bodyParam.vendorExtensions.put("consumesPlainText", true); op.bodyParam.vendorExtensions.put("consumesPlainText", true); // TODO: 5.0 Remove
op.bodyParam.vendorExtensions.put("x-consumes-plain-text", true);
} else { } else {
op.bodyParam.vendorExtensions.put("consumesJson", true); op.bodyParam.vendorExtensions.put("consumesJson", true); // TODO: 5.0 Remove
op.bodyParam.vendorExtensions.put("x-consumes-json", true);
} }
} }
for (CodegenParameter param : op.bodyParams) { for (CodegenParameter param : op.bodyParams) {
processParam(param, op); processParam(param, op);
param.vendorExtensions.put("uppercase_operation_id", underscore(op.operationId).toUpperCase(Locale.ROOT)); param.vendorExtensions.put("uppercase_operation_id", underscoredOperationId); // TODO: 5.0 Remove
param.vendorExtensions.put("x-uppercase-operation-id", underscoredOperationId);
// Default to producing json if nothing else is specified // Default to producing json if nothing else is specified
if (consumesXml) { if (consumesXml) {
param.vendorExtensions.put("consumesXml", true); param.vendorExtensions.put("consumesXml", true); // TODO: 5.0 Remove
param.vendorExtensions.put("x-consumes-xml", true);
} else if (consumesPlainText) { } else if (consumesPlainText) {
param.vendorExtensions.put("consumesPlainText", true); param.vendorExtensions.put("consumesPlainText", true); // TODO: 5.0 Remove
param.vendorExtensions.put("x-consumes-plain-text", true);
} else { } else {
param.vendorExtensions.put("consumesJson", true); param.vendorExtensions.put("consumesJson", true); // TODO: 5.0 Remove
param.vendorExtensions.put("x-consumes-json", true);
} }
} }
@ -885,7 +926,8 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
for (CodegenSecurity s : op.authMethods) { for (CodegenSecurity s : op.authMethods) {
if (s.isApiKey && s.isKeyInHeader) { if (s.isApiKey && s.isKeyInHeader) {
s.vendorExtensions.put("x-apiKeyName", toModelName(s.keyParamName)); s.vendorExtensions.put("x-apiKeyName", toModelName(s.keyParamName)); // TODO: 5.0 Remove
s.vendorExtensions.put("x-api-key-name", toModelName(s.keyParamName));
headerAuthMethods = true; headerAuthMethods = true;
} }
@ -895,7 +937,8 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
} }
if (headerAuthMethods) { if (headerAuthMethods) {
op.vendorExtensions.put("hasHeaderAuthMethods", "true"); op.vendorExtensions.put("hasHeaderAuthMethods", "true"); // TODO: 5.0 Remove
op.vendorExtensions.put("x-has-header-auth-methods", "true");
} }
} }
} }
@ -994,9 +1037,14 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
@Override @Override
public CodegenModel fromModel(String name, Schema model) { public CodegenModel fromModel(String name, Schema model) {
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
Map<String, Schema> allDefinitions = ModelUtils.getSchemas(this.openAPI); Map<String, Schema> allDefinitions = ModelUtils.getSchemas(this.openAPI);
CodegenModel mdl = super.fromModel(name, model); CodegenModel mdl = super.fromModel(name, model);
mdl.vendorExtensions.put("upperCaseName", name.toUpperCase(Locale.ROOT)); mdl.vendorExtensions.put("upperCaseName", name.toUpperCase(Locale.ROOT)); // TODO: 5.0 Remove
mdl.vendorExtensions.put("x-upper-case-name", name.toUpperCase(Locale.ROOT));
if (!StringUtils.isEmpty(model.get$ref())) { if (!StringUtils.isEmpty(model.get$ref())) {
Schema schema = allDefinitions.get(ModelUtils.getSimpleRef(model.get$ref())); Schema schema = allDefinitions.get(ModelUtils.getSimpleRef(model.get$ref()));
mdl.dataType = typeMapping.get(schema.getType()); mdl.dataType = typeMapping.get(schema.getType());
@ -1027,7 +1075,8 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
// If this model's items require wrapping in xml, squirrel away the // If this model's items require wrapping in xml, squirrel away the
// xml name so we can insert it into the relevant model fields. // xml name so we can insert it into the relevant model fields.
if (xmlName != null) { if (xmlName != null) {
mdl.vendorExtensions.put("itemXmlName", xmlName); mdl.vendorExtensions.put("itemXmlName", xmlName); // TODO: 5.0 Remove
mdl.vendorExtensions.put("x-item-xml-name", xmlName);
modelXmlNames.put("models::" + mdl.classname, xmlName); modelXmlNames.put("models::" + mdl.classname, xmlName);
} }
@ -1051,6 +1100,9 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
public Map<String, Object> postProcessAllModels(Map<String, Object> objs) { public Map<String, Object> postProcessAllModels(Map<String, Object> objs) {
Map<String, Object> newObjs = super.postProcessAllModels(objs); Map<String, Object> newObjs = super.postProcessAllModels(objs);
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
//Index all CodegenModels by model name. //Index all CodegenModels by model name.
HashMap<String, CodegenModel> allModels = new HashMap<String, CodegenModel>(); HashMap<String, CodegenModel> allModels = new HashMap<String, CodegenModel>();
for (Entry<String, Object> entry : objs.entrySet()) { for (Entry<String, Object> entry : objs.entrySet()) {
@ -1078,7 +1130,8 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
String xmlName = modelXmlNames.get(prop.dataType); String xmlName = modelXmlNames.get(prop.dataType);
if (xmlName != null) { if (xmlName != null) {
prop.vendorExtensions.put("itemXmlName", xmlName); prop.vendorExtensions.put("itemXmlName", xmlName); // TODO: 5.0 Remove
prop.vendorExtensions.put("x-item-xml-name", xmlName);
} }
} }
} }
@ -1249,6 +1302,10 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
@Override @Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) { public Map<String, Object> postProcessModels(Map<String, Object> objs) {
List<Object> models = (List<Object>) objs.get("models"); List<Object> models = (List<Object>) objs.get("models");
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
for (Object _mo : models) { for (Object _mo : models) {
Map<String, Object> mo = (Map<String, Object>) _mo; Map<String, Object> mo = (Map<String, Object>) _mo;
CodegenModel cm = (CodegenModel) mo.get("model"); CodegenModel cm = (CodegenModel) mo.get("model");
@ -1286,7 +1343,8 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
cm.dataType = typeMapping.get(cm.dataType); cm.dataType = typeMapping.get(cm.dataType);
} }
cm.vendorExtensions.put("isString", "String".equals(cm.dataType)); cm.vendorExtensions.put("isString", "String".equals(cm.dataType)); // TODO: 5.0 Remove
cm.vendorExtensions.put("x-is-string", "String".equals(cm.dataType));
} }
return super.postProcessModelsEnum(objs); return super.postProcessModelsEnum(objs);
} }
@ -1294,28 +1352,36 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
private void processParam(CodegenParameter param, CodegenOperation op) { private void processParam(CodegenParameter param, CodegenOperation op) {
String example = null; String example = null;
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
// If a parameter uses UUIDs, we need to import the UUID package. // If a parameter uses UUIDs, we need to import the UUID package.
if (param.dataType.equals(uuidType)) { if (param.dataType.equals(uuidType)) {
additionalProperties.put("apiUsesUuid", true); additionalProperties.put("apiUsesUuid", true);
} }
if (param.isString) { if (param.isString) {
param.vendorExtensions.put("formatString", "\\\"{}\\\""); param.vendorExtensions.put("formatString", "\\\"{}\\\""); // TODO: 5.0 Remove
param.vendorExtensions.put("x-format-string", "\\\"{}\\\""); // TODO: 5.0 Remove
example = "\"" + ((param.example != null) ? param.example : "") + "\".to_string()"; example = "\"" + ((param.example != null) ? param.example : "") + "\".to_string()";
} else if (param.isPrimitiveType) { } else if (param.isPrimitiveType) {
if ((param.isByteArray) || (param.isBinary)) { if ((param.isByteArray) || (param.isBinary)) {
// Binary primitive types don't implement `Display`. // Binary primitive types don't implement `Display`.
param.vendorExtensions.put("formatString", "{:?}"); param.vendorExtensions.put("formatString", "{:?}"); // TODO: 5.0 Remove
param.vendorExtensions.put("x-format-string", "{:?}");
example = "swagger::ByteArray(Vec::from(\"" + ((param.example != null) ? param.example : "") + "\"))"; example = "swagger::ByteArray(Vec::from(\"" + ((param.example != null) ? param.example : "") + "\"))";
} else { } else {
param.vendorExtensions.put("formatString", "{}"); param.vendorExtensions.put("formatString", "{}"); // TODO: 5.0 Remove
param.vendorExtensions.put("x-format-string", "{}");
example = (param.example != null) ? param.example : ""; example = (param.example != null) ? param.example : "";
} }
} else if (param.isListContainer) { } else if (param.isListContainer) {
param.vendorExtensions.put("formatString", "{:?}"); param.vendorExtensions.put("formatString", "{:?}"); // TODO: 5.0 Remove
param.vendorExtensions.put("x-format-string", "{:?}");
example = (param.example != null) ? param.example : "&Vec::new()"; example = (param.example != null) ? param.example : "&Vec::new()";
} else { } else {
param.vendorExtensions.put("formatString", "{:?}"); param.vendorExtensions.put("formatString", "{:?}"); // TODO: 5.0 Remove
param.vendorExtensions.put("x-format-string", "{:?}");
if (param.example != null) { if (param.example != null) {
example = "serde_json::from_str::<" + param.dataType + ">(\"" + param.example + "\").expect(\"Failed to parse JSON example\")"; example = "serde_json::from_str::<" + param.dataType + ">(\"" + param.example + "\").expect(\"Failed to parse JSON example\")";
} }
@ -1323,22 +1389,31 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
if (param.required) { if (param.required) {
if (example != null) { if (example != null) {
param.vendorExtensions.put("example", example); param.vendorExtensions.put("example", example); // TODO: 5.0 Remove
param.vendorExtensions.put("x-example", example);
} else if (param.isListContainer) { } else if (param.isListContainer) {
// Use the empty list if we don't have an example // Use the empty list if we don't have an example
param.vendorExtensions.put("example", "&Vec::new()"); param.vendorExtensions.put("example", "&Vec::new()"); // TODO: 5.0 Remove
param.vendorExtensions.put("x-example", "&Vec::new()");
} else { } else {
// If we don't have an example that we can provide, we need to disable the client example, as it won't build. // If we don't have an example that we can provide, we need to disable the client example, as it won't build.
param.vendorExtensions.put("example", "???"); param.vendorExtensions.put("example", "???"); // TODO: 5.0 Remove
op.vendorExtensions.put("noClientExample", Boolean.TRUE); param.vendorExtensions.put("x-example", "???");
op.vendorExtensions.put("noClientExample", Boolean.TRUE); // TODO: 5.0 Remove
op.vendorExtensions.put("x-no-client-example", Boolean.TRUE);
} }
} else if ((param.dataFormat != null) && ((param.dataFormat.equals("date-time")) || (param.dataFormat.equals("date")))) { } else if ((param.dataFormat != null) && ((param.dataFormat.equals("date-time")) || (param.dataFormat.equals("date")))) {
param.vendorExtensions.put("formatString", "{:?}"); param.vendorExtensions.put("formatString", "{:?}"); // TODO: 5.0 Remove
param.vendorExtensions.put("example", "None"); param.vendorExtensions.put("x-format-string", "{:?}");
param.vendorExtensions.put("example", "None"); // TODO: 5.0 Remove
param.vendorExtensions.put("x-example", "None");
} else { } else {
// Not required, so override the format string and example // Not required, so override the format string and example
param.vendorExtensions.put("formatString", "{:?}"); param.vendorExtensions.put("formatString", "{:?}"); // TODO: 5.0 Remove
param.vendorExtensions.put("example", (example != null) ? "Some(" + example + ")" : "None"); param.vendorExtensions.put("x-format-string", "{:?}");
String exampleString = (example != null) ? "Some(" + example + ")" : "None";
param.vendorExtensions.put("example", exampleString); // TODO: 5.0 Remove
param.vendorExtensions.put("x-example", exampleString);
} }
} }
} }

View File

@ -22,11 +22,16 @@ import io.swagger.v3.oas.models.media.Schema;
import org.openapitools.codegen.*; import org.openapitools.codegen.*;
import org.openapitools.codegen.meta.features.*; import org.openapitools.codegen.meta.features.*;
import org.openapitools.codegen.utils.ModelUtils; import org.openapitools.codegen.utils.ModelUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.util.*; import java.util.*;
import static org.openapitools.codegen.utils.OnceLogger.once;
public class ScalaFinchServerCodegen extends DefaultCodegen implements CodegenConfig { public class ScalaFinchServerCodegen extends DefaultCodegen implements CodegenConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(ScalaFinchServerCodegen.class);
protected String invokerPackage = "org.openapitools.client"; protected String invokerPackage = "org.openapitools.client";
protected String groupId = "org.openapitools"; protected String groupId = "org.openapitools";
protected String artifactId = "finch-server"; protected String artifactId = "finch-server";
@ -340,6 +345,10 @@ public class ScalaFinchServerCodegen extends DefaultCodegen implements CodegenCo
String authParams = ""; String authParams = "";
String authInputParams = ""; String authInputParams = "";
String typedAuthInputParams = ""; String typedAuthInputParams = "";
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
//Append apikey security to path params and create input parameters for functions //Append apikey security to path params and create input parameters for functions
if (op.authMethods != null) { if (op.authMethods != null) {
@ -356,9 +365,13 @@ public class ScalaFinchServerCodegen extends DefaultCodegen implements CodegenCo
} }
} }
op.vendorExtensions.put("x-codegen-authParams", authParams); op.vendorExtensions.put("x-codegen-authParams", authParams); // TODO: 5.0 Remove
op.vendorExtensions.put("x-codegen-authInputParams", authInputParams); op.vendorExtensions.put("x-codegen-authInputParams", authInputParams); // TODO: 5.0 Remove
op.vendorExtensions.put("x-codegen-typedAuthInputParams", typedAuthInputParams); op.vendorExtensions.put("x-codegen-typedAuthInputParams", typedAuthInputParams); // TODO: 5.0 Remove
op.vendorExtensions.put("x-codegen-auth-params", authParams);
op.vendorExtensions.put("x-codegen-auth-input-params", authInputParams);
op.vendorExtensions.put("x-codegen-typed-auth-input-params", typedAuthInputParams);
} }
private void generateScalaPath(CodegenOperation op) { private void generateScalaPath(CodegenOperation op) {
@ -402,6 +415,9 @@ public class ScalaFinchServerCodegen extends DefaultCodegen implements CodegenCo
private void concatParameters(CodegenOperation op) { private void concatParameters(CodegenOperation op) {
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
String path = colConcat(colConcat(op.vendorExtensions.get("x-codegen-path").toString(), op.vendorExtensions.get("x-codegen-pathParams").toString()), op.vendorExtensions.get("x-codegen-authParams").toString()); String path = colConcat(colConcat(op.vendorExtensions.get("x-codegen-path").toString(), op.vendorExtensions.get("x-codegen-pathParams").toString()), op.vendorExtensions.get("x-codegen-authParams").toString());
String parameters = csvConcat(op.vendorExtensions.get("x-codegen-inputParams").toString(), op.vendorExtensions.get("x-codegen-authInputParams").toString()); String parameters = csvConcat(op.vendorExtensions.get("x-codegen-inputParams").toString(), op.vendorExtensions.get("x-codegen-authInputParams").toString());
String typedParameters = csvConcat(op.vendorExtensions.get("x-codegen-typedInputParams").toString(), op.vendorExtensions.get("x-codegen-typedAuthInputParams").toString()); String typedParameters = csvConcat(op.vendorExtensions.get("x-codegen-typedInputParams").toString(), op.vendorExtensions.get("x-codegen-typedAuthInputParams").toString());
@ -409,13 +425,17 @@ public class ScalaFinchServerCodegen extends DefaultCodegen implements CodegenCo
// The input parameters for functions // The input parameters for functions
op.vendorExtensions.put("x-codegen-paths", path); op.vendorExtensions.put("x-codegen-paths", path);
op.vendorExtensions.put("x-codegen-params", parameters); op.vendorExtensions.put("x-codegen-params", parameters);
op.vendorExtensions.put("x-codegen-typedParams", typedParameters); op.vendorExtensions.put("x-codegen-typedParams", typedParameters); // TODO: 5.0 Remove
op.vendorExtensions.put("x-codegen-typed-params", typedParameters);
} }
private void generateInputParameters(CodegenOperation op) { private void generateInputParameters(CodegenOperation op) {
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
String inputParams = ""; String inputParams = "";
String typedInputParams = ""; String typedInputParams = "";
String pathParams = ""; String pathParams = "";
@ -462,11 +482,14 @@ public class ScalaFinchServerCodegen extends DefaultCodegen implements CodegenCo
} }
// All body, path, query and header parameters // All body, path, query and header parameters
op.vendorExtensions.put("x-codegen-pathParams", pathParams); op.vendorExtensions.put("x-codegen-pathParams", pathParams); // TODO: 5.0 Remove
op.vendorExtensions.put("x-codegen-path-params", pathParams);
// The input parameters for functions // The input parameters for functions
op.vendorExtensions.put("x-codegen-inputParams", inputParams); op.vendorExtensions.put("x-codegen-inputParams", inputParams); // TODO: 5.0 Remove
op.vendorExtensions.put("x-codegen-typedInputParams", typedInputParams); op.vendorExtensions.put("x-codegen-input-params", inputParams);
op.vendorExtensions.put("x-codegen-typedInputParams", typedInputParams); // TODO: 5.0 Remove
op.vendorExtensions.put("x-codegen-typed-input-params", typedInputParams);
} }

View File

@ -35,6 +35,7 @@ import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.apache.commons.lang3.StringUtils.rightPad; import static org.apache.commons.lang3.StringUtils.rightPad;
import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.camelize; import static org.openapitools.codegen.utils.StringUtils.camelize;
public class ScalaPlayFrameworkServerCodegen extends AbstractScalaCodegen implements CodegenConfig { public class ScalaPlayFrameworkServerCodegen extends AbstractScalaCodegen implements CodegenConfig {
@ -255,6 +256,9 @@ public class ScalaPlayFrameworkServerCodegen extends AbstractScalaCodegen implem
objs = super.postProcessAllModels(objs); objs = super.postProcessAllModels(objs);
Map<String, CodegenModel> modelsByClassName = new HashMap<>(); Map<String, CodegenModel> modelsByClassName = new HashMap<>();
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
for (Object _outer : objs.values()) { for (Object _outer : objs.values()) {
Map<String, Object> outer = (Map<String, Object>) _outer; Map<String, Object> outer = (Map<String, Object>) _outer;
List<Map<String, Object>> models = (List<Map<String, Object>>) outer.get("models"); List<Map<String, Object>> models = (List<Map<String, Object>>) outer.get("models");
@ -265,7 +269,8 @@ public class ScalaPlayFrameworkServerCodegen extends AbstractScalaCodegen implem
cm.classVarName = camelize(cm.classVarName, true); cm.classVarName = camelize(cm.classVarName, true);
modelsByClassName.put(cm.classname, cm); modelsByClassName.put(cm.classname, cm);
boolean hasFiles = cm.vars.stream().anyMatch(var -> var.isFile); boolean hasFiles = cm.vars.stream().anyMatch(var -> var.isFile);
cm.vendorExtensions.put("hasFiles", hasFiles); cm.vendorExtensions.put("hasFiles", hasFiles); // TODO: 5.0 Remove
cm.vendorExtensions.put("x-has-files", hasFiles);
} }
} }
@ -282,6 +287,9 @@ public class ScalaPlayFrameworkServerCodegen extends AbstractScalaCodegen implem
objs = super.postProcessSupportingFileData(objs); objs = super.postProcessSupportingFileData(objs);
generateJSONSpecFile(objs); generateJSONSpecFile(objs);
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
// Prettify routes file // Prettify routes file
Map<String, Object> apiInfo = (Map<String, Object>) objs.get("apiInfo"); Map<String, Object> apiInfo = (Map<String, Object>) objs.get("apiInfo");
List<Map<String, Object>> apis = (List<Map<String, Object>>) apiInfo.get("apis"); List<Map<String, Object>> apis = (List<Map<String, Object>>) apiInfo.get("apis");
@ -292,8 +300,15 @@ public class ScalaPlayFrameworkServerCodegen extends AbstractScalaCodegen implem
int maxPathLength = ops.stream() int maxPathLength = ops.stream()
.mapToInt(op -> op.httpMethod.length() + op.path.length()) .mapToInt(op -> op.httpMethod.length() + op.path.length())
.reduce(0, Integer::max); .reduce(0, Integer::max);
ops.forEach(op -> op.vendorExtensions.put("paddedPath", rightPad(op.path, maxPathLength - op.httpMethod.length()))); ops.forEach(op -> {
ops.forEach(op -> op.vendorExtensions.put("hasPathParams", op.getHasPathParams())); String paddedPath = rightPad(op.path, maxPathLength - op.httpMethod.length());
op.vendorExtensions.put("paddedPath", paddedPath); // TODO: 5.0 Remove
op.vendorExtensions.put("x-padded-path", paddedPath);
});
ops.forEach(op -> {
op.vendorExtensions.put("hasPathParams", op.getHasPathParams()); // TODO: 5.0 Remove
op.vendorExtensions.put("x-has-path-params", op.getHasPathParams());
});
return objs; return objs;
} }

View File

@ -35,6 +35,7 @@ import org.slf4j.LoggerFactory;
import java.util.*; import java.util.*;
import static org.openapitools.codegen.utils.OnceLogger.once;
import static org.openapitools.codegen.utils.StringUtils.*; import static org.openapitools.codegen.utils.StringUtils.*;
public class StaticHtml2Generator extends DefaultCodegen implements CodegenConfig { public class StaticHtml2Generator extends DefaultCodegen implements CodegenConfig {
@ -201,13 +202,20 @@ public class StaticHtml2Generator extends DefaultCodegen implements CodegenConfi
@Override @Override
public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, List<Server> servers) { public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, List<Server> servers) {
CodegenOperation op = super.fromOperation(path, httpMethod, operation, servers); CodegenOperation op = super.fromOperation(path, httpMethod, operation, servers);
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
if (op.returnType != null) { if (op.returnType != null) {
op.returnType = normalizeType(op.returnType); op.returnType = normalizeType(op.returnType);
} }
//path is an unescaped variable in the mustache template api.mustache line 82 '<&path>' //path is an unescaped variable in the mustache template api.mustache line 82 '<&path>'
op.path = sanitizePath(op.path); op.path = sanitizePath(op.path);
op.vendorExtensions.put("x-codegen-httpMethodUpperCase", httpMethod.toUpperCase(Locale.ROOT));
String methodUpperCase = httpMethod.toUpperCase(Locale.ROOT);
op.vendorExtensions.put("x-codegen-httpMethodUpperCase", methodUpperCase); // TODO: 5.0 Remove
op.vendorExtensions.put("x-codegen-http-method-upper-case", methodUpperCase);
return op; return op;
} }
@ -239,6 +247,10 @@ public class StaticHtml2Generator extends DefaultCodegen implements CodegenConfi
*/ */
public List<CodegenParameter> postProcessParameterEnum(List<CodegenParameter> parameterList) { public List<CodegenParameter> postProcessParameterEnum(List<CodegenParameter> parameterList) {
String enumFormatted = ""; String enumFormatted = "";
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
for (CodegenParameter parameter : parameterList) { for (CodegenParameter parameter : parameterList) {
if (parameter.isEnum) { if (parameter.isEnum) {
for (int i = 0; i < parameter._enum.size(); i++) { for (int i = 0; i < parameter._enum.size(); i++) {
@ -248,8 +260,11 @@ public class StaticHtml2Generator extends DefaultCodegen implements CodegenConfi
enumFormatted += "`" + parameter._enum.get(i) + "`" + spacer; enumFormatted += "`" + parameter._enum.get(i) + "`" + spacer;
} }
Markdown markInstance = new Markdown(); Markdown markInstance = new Markdown();
if (!enumFormatted.isEmpty()) if (!enumFormatted.isEmpty()) {
parameter.vendorExtensions.put("x-eumFormatted", markInstance.toHtml(enumFormatted)); String formattedExtension = markInstance.toHtml(enumFormatted);
parameter.vendorExtensions.put("x-eumFormatted", formattedExtension); // TODO: 5.0 Remove
parameter.vendorExtensions.put("x-eum-formatted", formattedExtension);
}
} }
} }
return parameterList; return parameterList;

View File

@ -29,6 +29,8 @@ import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.util.*; import java.util.*;
import static org.openapitools.codegen.utils.OnceLogger.once;
public class TypeScriptRxjsClientCodegen extends AbstractTypeScriptClientCodegen { public class TypeScriptRxjsClientCodegen extends AbstractTypeScriptClientCodegen {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractTypeScriptClientCodegen.class); private static final Logger LOGGER = LoggerFactory.getLogger(AbstractTypeScriptClientCodegen.class);
@ -259,8 +261,13 @@ public class TypeScriptRxjsClientCodegen extends AbstractTypeScriptClientCodegen
} }
private void setParamNameAlternative(CodegenParameter param, String paramName, String paramNameAlternative) { private void setParamNameAlternative(CodegenParameter param, String paramName, String paramNameAlternative) {
// TODO: 5.0: Remove the camelCased vendorExtension below and ensure templates use the newer property naming.
once(LOGGER).warn("4.3.0 has deprecated the use of vendor extensions which don't follow lower-kebab casing standards with x- prefix.");
if (param.paramName.equals(paramName)) { if (param.paramName.equals(paramName)) {
param.vendorExtensions.put("paramNameAlternative", paramNameAlternative); param.vendorExtensions.put("paramNameAlternative", paramNameAlternative); // TODO: 5.0 Remove
param.vendorExtensions.put("x-param-name-alternative", paramNameAlternative);
} }
} }

View File

@ -0,0 +1,173 @@
package org.openapitools.codegen.utils;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.Ticker;
import org.openapitools.codegen.config.GlobalSettings;
import org.slf4j.Logger;
import org.slf4j.Marker;
import org.slf4j.MarkerFactory;
import org.slf4j.ext.LoggerWrapper;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Provides calling code a way to log important messages only once, regardless of how many times the invocation has occurred.
* This can be used, for instance, to log a warning like "One or more schemas aren't declared" without logging that message
* for every time the schema is mentioned in a document.
*
* This implementation currently only supports single-argument string literal log methods (e.g. {@link Logger#debug(String)}).
*/
@SuppressWarnings("FieldCanBeLocal")
public class OnceLogger extends LoggerWrapper {
/**
* Allow advanced users to modify cache size of the OnceLogger (more for performance tuning in hosted environments)
*/
static final String CACHE_SIZE_PROPERTY = "org.openapitools.codegen.utils.oncelogger.cachesize";
/**
* Allow advanced users to disable the OnceLogger (more for performance tuning in hosted environments).
* This is really only useful or necessary if this implementation causes issues.
*/
static final String ENABLE_ONCE_LOGGER_PROPERTY = "org.openapitools.codegen.utils.oncelogger.enabled";
/**
* Allow advanced users to modify cache expiration of the OnceLogger (more for performance tuning in hosted environments)
*/
static final String EXPIRY_PROPERTY = "org.openapitools.codegen.utils.oncelogger.expiry";
/**
* Internal message cache for logger decorated with the onceler.
*/
static Cache<String, AtomicInteger> messageCountCache;
/**
* The fully qualified class name of the <b>logger instance</b>,
* typically the logger class, logger bridge or a logger wrapper.
*/
private static final String FQCN = OnceLogger.class.getName();
/**
* Gets the marker instance. This can be used by supported log implementations to filter/manage logs coming from
* this implementation differently than others (i.e. make them stand out since they're to be logged once).
*/
private static final Marker MARKER = MarkerFactory.getMarker("ONCE");
/**
* The allowed size of the cache.
*/
private static int maxCacheSize = Integer.parseInt(GlobalSettings.getProperty(CACHE_SIZE_PROPERTY, "200"));
/**
* The millis to expire a cached log message.
*/
private static int expireMillis = Integer.parseInt(GlobalSettings.getProperty(EXPIRY_PROPERTY, "2000"));
/**
* The number of allowed repetitions.
*/
private static int maxRepetitions = 1;
OnceLogger(Logger logger) {
this(logger, FQCN);
}
OnceLogger(Logger logger, String fqcn) {
super(logger, fqcn);
}
static {
caffeineCache(Ticker.systemTicker(), expireMillis);
}
static void caffeineCache(Ticker ticker, int expireMillis) {
// Initializes a cache which holds an atomic counter of log message instances.
// The intent is to debounce log messages such that they occur at most [maxRepetitions] per [expireMillis].
messageCountCache = Caffeine.newBuilder()
.maximumSize(maxCacheSize)
.expireAfterWrite(expireMillis, TimeUnit.MILLISECONDS)
.ticker(ticker)
.build();
}
public static Logger once(Logger logger) {
try {
if (Boolean.parseBoolean(GlobalSettings.getProperty(ENABLE_ONCE_LOGGER_PROPERTY, "true"))) {
return new OnceLogger(logger);
}
} catch (Exception ex) {
logger.warn("Unable to wrap logger instance in OnceLogger. Falling back to non-decorated implementation, which may be noisy.");
}
return logger;
}
/**
* Delegate to the appropriate method of the underlying logger.
*
* @param msg The log message.
*/
@Override
public void trace(String msg) {
if (!isTraceEnabled() || !isTraceEnabled(MARKER)) return;
if (shouldLog(msg)) super.trace(MARKER, msg);
}
@SuppressWarnings("ConstantConditions")
private boolean shouldLog(final String msg) {
AtomicInteger counter = messageCountCache.get(msg, i -> new AtomicInteger(0));
return counter.incrementAndGet() <= maxRepetitions;
}
/**
* Delegate to the appropriate method of the underlying logger.
*
* @param msg The log message.
*/
@Override
public void debug(String msg) {
if (!isDebugEnabled() || !isDebugEnabled(MARKER)) return;
if (shouldLog(msg)) super.debug(MARKER, msg);
}
/**
* Delegate to the appropriate method of the underlying logger.
*
* @param msg The log message.
*/
@Override
public void info(String msg) {
if (!isInfoEnabled() || !isInfoEnabled(MARKER)) return;
if (shouldLog(msg)) super.info(MARKER, msg);
}
/**
* Delegate to the appropriate method of the underlying logger.
*
* @param msg The log message.
*/
@Override
public void warn(String msg) {
if (!isWarnEnabled() || !isWarnEnabled(MARKER)) return;
if (shouldLog(msg)) super.warn(MARKER, msg);
}
/**
* Delegate to the appropriate method of the underlying logger.
*
* Use this method sparingly. If you're limiting error messages, ask yourself
* whether your log fits better as a warning.
*
* @param msg The log message.
*/
@Override
public void error(String msg) {
if (!isErrorEnabled() || !isErrorEnabled(MARKER)) return;
if (shouldLog(msg)) super.error(MARKER, msg);
}
}

View File

@ -0,0 +1,114 @@
package org.openapitools.codegen.utils;
import com.google.common.base.Ticker;
import com.google.common.testing.FakeTicker;
import org.mockito.Mockito;
import org.openapitools.codegen.config.GlobalSettings;
import org.slf4j.Logger;
import org.slf4j.Marker;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import static org.mockito.Mockito.*;
import static org.openapitools.codegen.utils.OnceLogger.*;
import static org.testng.Assert.*;
@SuppressWarnings({"SameParameterValue", "UnstableApiUsage"})
public class OnceLoggerTest {
private Logger mockLogger = Mockito.mock(Logger.class);
private FakeTicker ticker = new FakeTicker();
@BeforeTest
public void setUp(){
OnceLogger.caffeineCache(ticker::read, 1000);
}
@AfterMethod
public void afterEach() {
OnceLogger.messageCountCache.asMap().clear();
}
@BeforeMethod
public void beforeEach() {
Mockito.reset(mockLogger);
}
@Test
public void onceLogsMessagesOnceWithinTimeLimit() throws InterruptedException {
String message = "onceLogsMessagesOnceWithinTimeLimit";
Logger instance = once(mockLogger);
when(mockLogger.isWarnEnabled()).thenReturn(true);
when(mockLogger.isWarnEnabled(any(Marker.class))).thenReturn(true);
for (int i = 0; i < 50; i++) {
instance.warn(message);
}
AtomicInteger counter1 = messageCountCache.getIfPresent(message);
assertNotNull(counter1);
assertEquals(counter1.get(), 50);
ticker.advance(1100L, TimeUnit.MILLISECONDS);
AtomicInteger noCounter = messageCountCache.getIfPresent(message);
assertNull(noCounter);
verify(mockLogger, times(1)).warn(any(Marker.class), same(message));
for (int i = 0; i < 50; i++) {
instance.warn(message);
}
ticker.advance(5, TimeUnit.MILLISECONDS);
AtomicInteger counter2 = messageCountCache.getIfPresent(message);
assertNotNull(counter2);
assertNotEquals(counter2, counter1);
assertEquals(counter2.get(), 50);
verify(mockLogger, times(2)).warn(any(Marker.class), same(message));
}
@Test
public void onceLogsOneMessageByDefault() {
String message = "onceLogsOneMessageByDefault";
Logger instance = once(mockLogger);
when(mockLogger.isWarnEnabled()).thenReturn(true);
when(mockLogger.isWarnEnabled(any(Marker.class))).thenReturn(true);
for (int i = 0; i < 50; i++) {
instance.warn(message);
}
verify(mockLogger, times(1)).warn(any(Marker.class), same(message));
}
@Test
public void onceReturnsDecoratedLogger() {
Logger instance = once(mockLogger);
assertTrue(instance instanceof OnceLogger);
}
@Test
public void onceReturnsOriginalLoggerWhenDisabled() {
String originalSetting = GlobalSettings.getProperty(ENABLE_ONCE_LOGGER_PROPERTY);
try {
GlobalSettings.setProperty(ENABLE_ONCE_LOGGER_PROPERTY, "false");
Logger instance = once(mockLogger);
assertFalse(instance instanceof OnceLogger);
} finally {
resetGlobalProperty(ENABLE_ONCE_LOGGER_PROPERTY, originalSetting);
}
}
private void resetGlobalProperty(String key, String value) {
if (value != null)
GlobalSettings.setProperty(key, value);
else
GlobalSettings.clearProperty(key);
}
}

View File

@ -225,6 +225,9 @@
<junitArtifactName>none:none</junitArtifactName> <junitArtifactName>none:none</junitArtifactName>
<testNGArtifactName>org.testng:testng</testNGArtifactName> <testNGArtifactName>org.testng:testng</testNGArtifactName>
<argLine>@{argLine} -XX:+StartAttachListener</argLine> <argLine>@{argLine} -XX:+StartAttachListener</argLine>
<systemPropertyVariables>
<org.openapitools.codegen.utils.oncelogger.expiry>1000</org.openapitools.codegen.utils.oncelogger.expiry>
</systemPropertyVariables>
</configuration> </configuration>
<dependencies> <dependencies>
<dependency> <dependency>