Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
ad798de
break tests by introducing problematic dollar
Picazsoo Nov 26, 2025
b25bb65
break everything by more defaults and dollars and double quotes
Picazsoo Nov 27, 2025
4c6e186
break everything even more
Picazsoo Nov 27, 2025
b4f370d
break everything consistently to make CR easier
Picazsoo Nov 27, 2025
884975a
fix as much as possible
Picazsoo Nov 27, 2025
8f207b5
fix more places
Picazsoo Nov 27, 2025
319c55d
remove files
Picazsoo Nov 27, 2025
b41dc70
removed some files
Picazsoo Nov 27, 2025
907f878
fix one more place
Picazsoo Nov 27, 2025
c9ce225
DRY tests
Picazsoo Nov 27, 2025
a86a9f1
add unit test
Picazsoo Nov 27, 2025
5485eab
improve unit test
Picazsoo Nov 27, 2025
b89a2f1
add dollar escaping for multiline strings
Picazsoo Nov 27, 2025
d2e3ba1
add dollar escaping for multiline strings and test
Picazsoo Nov 27, 2025
9622ddd
add more compilation tests and extend some current compilations to al…
Picazsoo Nov 27, 2025
8b838c6
fix compilation error
Picazsoo Nov 27, 2025
baefe50
fix one more place
Picazsoo Nov 27, 2025
acce9f3
fix incorrect test assert after fixing api spec "required" attribute
Picazsoo Nov 27, 2025
6def290
try disabling tests
Picazsoo Nov 27, 2025
378250c
comment out the tests to disable them
Picazsoo Nov 27, 2025
f4a1cc5
fix tests on linux
Picazsoo Nov 27, 2025
c350638
also add compile tests for interface_only to show multiline dollar es…
Picazsoo Nov 27, 2025
bd6c1ef
fix samples up to date
Picazsoo Nov 28, 2025
da86be4
fix samples up to date
Picazsoo Nov 28, 2025
7a65094
fix javadoc
Picazsoo Nov 28, 2025
f6692f4
update samples
Picazsoo Nov 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/samples-kotlin-server-jdk17.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ jobs:
- samples/server/petstore/kotlin-server-required-and-nullable-properties
- samples/server/petstore/kotlin-springboot-3
- samples/server/petstore/kotlin-springboot-3-no-response-entity
- samples/server/petstore/kotlin-springboot-3-dollar-issue-swagger2
- samples/server/petstore/kotlin-springboot-3-dollar-issue-swagger2-interface-only
- samples/server/petstore/kotlin-springboot-additionalproperties
- samples/server/petstore/kotlin-springboot-delegate-nodefaults
- samples/server/petstore/kotlin-springboot-request-cookie
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/samples-kotlin-server.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ jobs:
- samples/server/petstore/kotlin-springboot-source-swagger2
- samples/server/petstore/kotlin-springboot-springfox
- samples/server/petstore/kotlin-springboot-x-kotlin-implements
- samples/server/petstore/kotlin-springboot-dollar-issue-swagger1
- samples/server/petstore/kotlin-springboot-include-http-request-context-delegate
- samples/server/petstore/kotlin-server/ktor
- samples/server/petstore/kotlin-server/ktor2
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
generatorName: kotlin-spring
outputDir: samples/server/petstore/kotlin-springboot-3-dollar-issue-swagger2-interface-only
library: spring-boot
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore-with-dollars.yaml
templateDir: modules/openapi-generator/src/main/resources/kotlin-spring
additionalProperties:
documentationProvider: springDoc
annotationLibrary: swagger2
useSwaggerUI: "false"
interfaceOnly: "true"
serializableModel: "true"
beanValidations: "true"
useSpringBoot3: "true"
requestMappingMode: api_interface
14 changes: 14 additions & 0 deletions bin/configs/kotlin-spring-boot-3-dollar-issue-swagger2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
generatorName: kotlin-spring
outputDir: samples/server/petstore/kotlin-springboot-3-dollar-issue-swagger2
library: spring-boot
inputSpec: modules/openapi-generator/src/test/resources/3_0/kotlin/petstore-with-tags.yaml
templateDir: modules/openapi-generator/src/main/resources/kotlin-spring
additionalProperties:
documentationProvider: springDoc
annotationLibrary: swagger2
useSwaggerUI: "false"
serviceImplementation: "true"
serializableModel: "true"
beanValidations: "true"
useSpringBoot3: "true"
requestMappingMode: api_interface
13 changes: 13 additions & 0 deletions bin/configs/kotlin-spring-boot-dollar-issue-swagger1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
generatorName: kotlin-spring
outputDir: samples/server/petstore/kotlin-springboot-dollar-issue-swagger1
library: spring-boot
inputSpec: modules/openapi-generator/src/test/resources/3_0/kotlin/petstore-with-tags.yaml
templateDir: modules/openapi-generator/src/main/resources/kotlin-spring
additionalProperties:
documentationProvider: springFox
annotationLibrary: swagger1
useSwaggerUI: "false"
serviceImplementation: "true"
serializableModel: "true"
beanValidations: "true"
requestMappingMode: api_interface
2 changes: 1 addition & 1 deletion bin/configs/kotlin-spring-boot-x-kotlin-implements.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ additionalProperties:
useSwaggerUI: false
serviceImplementation: false
skipDefaultInterface: true
interfaceOnly: true
interfaceOnly: false
serializableModel: true
beanValidations: true
includeHttpRequestContext: true
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
generatorName: kotlin-spring
outputDir: samples/server/petstore/kotlin-spring-declarative-interface-reactive-coroutines
library: spring-declarative-http-interface
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore-with-dollars.yaml
templateDir: modules/openapi-generator/src/main/resources/kotlin-spring
additionalProperties:
documentationProvider: springDoc
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
generatorName: kotlin-spring
outputDir: samples/server/petstore/kotlin-spring-declarative-interface-reactive-reactor-wrapped
library: spring-declarative-http-interface
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore-with-dollars.yaml
templateDir: modules/openapi-generator/src/main/resources/kotlin-spring
additionalProperties:
documentationProvider: springDoc
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
generatorName: kotlin-spring
outputDir: samples/server/petstore/kotlin-spring-declarative-interface-wrapped
library: spring-declarative-http-interface
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore-with-dollars.yaml
templateDir: modules/openapi-generator/src/main/resources/kotlin-spring
additionalProperties:
documentationProvider: springDoc
Expand Down
2 changes: 1 addition & 1 deletion bin/configs/kotlin-spring-declarative-interface.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
generatorName: kotlin-spring
outputDir: samples/server/petstore/kotlin-spring-declarative-interface
library: spring-declarative-http-interface
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore-with-dollars.yaml
templateDir: modules/openapi-generator/src/main/resources/kotlin-spring
additionalProperties:
documentationProvider: springDoc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class CodegenOperation {
hasErrorResponseObject; // if 4xx, 5xx responses have at least one error object defined
public CodegenProperty returnProperty;
public String path, operationId, returnType, returnFormat, httpMethod, returnBaseType,
returnContainer, summary, unescapedNotes, notes, baseName, defaultResponse;
returnContainer, summary, unescapedSummary, unescapedNotes, notes, baseName, defaultResponse;
public CodegenDiscriminator discriminator;
public List<Map<String, String>> consumes, produces, prioritizedContentTypes;
public List<CodegenServer> servers = new ArrayList<CodegenServer>();
Expand Down Expand Up @@ -429,6 +429,7 @@ public String toString() {
sb.append(", returnBaseType='").append(returnBaseType).append('\'');
sb.append(", returnContainer='").append(returnContainer).append('\'');
sb.append(", summary='").append(summary).append('\'');
sb.append(", unescapedSummary='").append(unescapedSummary).append('\'');
sb.append(", unescapedNotes='").append(unescapedNotes).append('\'');
sb.append(", notes='").append(notes).append('\'');
sb.append(", baseName='").append(baseName).append('\'');
Expand Down Expand Up @@ -502,6 +503,7 @@ public boolean equals(Object o) {
Objects.equals(returnBaseType, that.returnBaseType) &&
Objects.equals(returnContainer, that.returnContainer) &&
Objects.equals(summary, that.summary) &&
Objects.equals(unescapedSummary, that.unescapedSummary) &&
Objects.equals(unescapedNotes, that.unescapedNotes) &&
Objects.equals(notes, that.notes) &&
Objects.equals(baseName, that.baseName) &&
Expand Down Expand Up @@ -547,7 +549,7 @@ public int hashCode() {
returnTypeIsPrimitive, returnSimpleType, subresourceOperation, isMap,
isArray, isMultipart, isVoid, isResponseBinary, isResponseFile, isResponseOptional, hasReference,
isDeprecated, isCallbackRequest, uniqueItems, path, operationId, returnType, httpMethod,
returnBaseType, returnContainer, summary, unescapedNotes, notes, baseName, defaultResponse,
returnBaseType, returnContainer, summary, unescapedSummary, unescapedNotes, notes, baseName, defaultResponse,
discriminator, consumes, produces, prioritizedContentTypes, servers, bodyParam, allParams, bodyParams,
pathParams, queryParams, headerParams, formParams, cookieParams, requiredParams, returnProperty, optionalParams,
authMethods, tags, responses, callbacks, imports, examples, requestBodyExamples, externalDocs,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public class CodegenResponse implements IJsonSchemaValidationProperties {
public boolean is4xx;
public boolean is5xx;
public String message;
public String unescapedMessage;
public List<Map<String, Object>> examples;
public String dataType;
public String baseType;
Expand Down Expand Up @@ -109,7 +110,7 @@ public class CodegenResponse implements IJsonSchemaValidationProperties {

@Override
public int hashCode() {
return Objects.hash(headers, code, message, examples, dataType, baseType, containerType, containerTypeMapped, hasHeaders,
return Objects.hash(headers, code, message, unescapedMessage, examples, dataType, baseType, containerType, containerTypeMapped, hasHeaders,
isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isDecimal, isByteArray, isBoolean, isDate,
isDateTime, isUuid, isEmail, isPassword, isModel, isFreeFormObject, isAnyType, isDefault, simpleType, primitiveType,
isMap, isOptional, isArray, isBinary, isFile, schema, jsonSchema, vendorExtensions, items, additionalProperties,
Expand Down Expand Up @@ -182,6 +183,7 @@ public boolean equals(Object o) {
Objects.equals(headers, that.headers) &&
Objects.equals(code, that.code) &&
Objects.equals(message, that.message) &&
Objects.equals(unescapedMessage, that.unescapedMessage) &&
Objects.equals(examples, that.examples) &&
Objects.equals(dataType, that.dataType) &&
Objects.equals(baseType, that.baseType) &&
Expand Down Expand Up @@ -582,6 +584,7 @@ public String toString() {
sb.append(", is4xx='").append(is4xx).append('\'');
sb.append(", is5xx='").append(is5xx).append('\'');
sb.append(", message='").append(message).append('\'');
sb.append(", unescapedMessage='").append(unescapedMessage).append('\'');
sb.append(", examples=").append(examples);
sb.append(", dataType='").append(dataType).append('\'');
sb.append(", baseType='").append(baseType).append('\'');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4675,6 +4675,7 @@ public CodegenOperation fromOperation(String path,
}

op.summary = escapeText(operation.getSummary());
op.unescapedSummary = operation.getSummary();
op.unescapedNotes = operation.getDescription();
op.notes = escapeText(operation.getDescription());
op.hasConsumes = false;
Expand Down Expand Up @@ -4839,6 +4840,7 @@ public CodegenOperation fromOperation(String path,

if (bodyParam != null) {
bodyParam.description = escapeText(requestBody.getDescription());
bodyParam.unescapedDescription = requestBody.getDescription();
postProcessParameter(bodyParam);
bodyParams.add(bodyParam);
if (prependFormOrBodyParameters) {
Expand Down Expand Up @@ -5029,6 +5031,7 @@ public CodegenResponse fromResponse(String responseCode, ApiResponse response) {
}
r.schema = responseSchema;
r.message = escapeText(response.getDescription());
r.unescapedMessage = response.getDescription();

// adding examples to API responses
Map<String, Example> examples = ExamplesUtils.getExamplesFromResponse(openAPI, response);
Expand Down Expand Up @@ -7575,6 +7578,7 @@ protected void addBodyModelSchema(CodegenParameter codegenParameter, String name
codegenParameter.baseType = codegenModel.classname;
codegenParameter.dataType = getTypeDeclaration(codegenModel.classname);
codegenParameter.description = codegenModel.description;
codegenParameter.unescapedDescription = codegenModel.unescapedDescription;
codegenParameter.isNullable = codegenModel.isNullable;
imports.add(codegenParameter.baseType);
} else {
Expand Down Expand Up @@ -7948,6 +7952,7 @@ public CodegenParameter fromRequestBody(RequestBody body, Set<String> imports, S
codegenParameter.baseName = "UNKNOWN_BASE_NAME";
codegenParameter.paramName = "UNKNOWN_PARAM_NAME";
codegenParameter.description = escapeText(body.getDescription());
codegenParameter.unescapedDescription = body.getDescription();
codegenParameter.required = body.getRequired() != null ? body.getRequired() : Boolean.FALSE;
codegenParameter.isBodyParam = Boolean.TRUE;
if (body.getExtensions() != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1131,7 +1131,8 @@ protected void updateModelForObject(CodegenModel m, Schema schema) {
@Override
protected ImmutableMap.Builder<String, Mustache.Lambda> addMustacheLambdas() {
return super.addMustacheLambdas()
.put("escapeDollar", new EscapeChar("(?<!\\\\)\\$", "\\\\\\$"));
.put("escapeDollar", new EscapeChar("(?<!\\\\)\\$", "\\\\\\$"))
.put("escapeDollarInMultiline", new EscapeChar("(?<!\\\\)\\$", "\\${'\\$'}"));
}

protected interface DataTypeAssigner {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,25 +73,27 @@ class {{classname}}Controller({{#serviceInterface}}@Autowired(required = true) v
}}{{/useResponseEntity}}{{!
}}{{#swagger2AnnotationLibrary}}{{!
}} @Operation(
summary = "{{{summary}}}",
summary = "{{#lambda.escapeDollar}}{{{summary}}}{{/lambda.escapeDollar}}",
operationId = "{{{operationId}}}",
description = """{{{unescapedNotes}}}""",
description = """{{#lambda.escapeDollarInMultiline}}{{{unescapedNotes}}}{{/lambda.escapeDollarInMultiline}}""",
responses = [{{#responses}}
ApiResponse(responseCode = "{{{code}}}", description = "{{{message}}}"{{#baseType}}, content = [Content({{#isArray}}array = ArraySchema({{/isArray}}schema = Schema(implementation = {{{baseType}}}::class)){{#isArray}}){{/isArray}}]{{/baseType}}){{^-last}},{{/-last}}{{/responses}} ]{{#hasAuthMethods}},
ApiResponse(responseCode = "{{{code}}}", description = "{{#lambda.escapeDollar}}{{{message}}}{{/lambda.escapeDollar}}"{{#baseType}}, content = [Content({{#isArray}}array = ArraySchema({{/isArray}}schema = Schema(implementation = {{{baseType}}}::class)){{#isArray}}){{/isArray}}]{{/baseType}}){{^-last}},{{/-last}}{{/responses}} ]{{#hasAuthMethods}},
security = [ {{#authMethods}}SecurityRequirement(name = "{{name}}"{{#isOAuth}}, scopes = [ {{#scopes}}"{{scope}}"{{^-last}}, {{/-last}}{{/scopes}} ]{{/isOAuth}}){{^-last}},{{/-last}}{{/authMethods}} ]{{/hasAuthMethods}}
){{/swagger2AnnotationLibrary}}{{#swagger1AnnotationLibrary}}
@ApiOperation(
value = "{{{summary}}}",
value = "{{#lambda.escapeDollar}}{{{summary}}}{{/lambda.escapeDollar}}",
nickname = "{{{operationId}}}",
notes = "{{{notes}}}"{{#returnBaseType}},
notes = "{{#lambda.escapeDollar}}{{{notes}}}{{/lambda.escapeDollar}}"{{#returnBaseType}},
response = {{{.}}}::class{{/returnBaseType}}{{#returnContainer}},
responseContainer = "{{{.}}}"{{/returnContainer}}{{#hasAuthMethods}},
authorizations = [{{#authMethods}}Authorization(value = "{{name}}"{{#isOAuth}}, scopes = [{{#scopes}}AuthorizationScope(scope = "{{scope}}", description = "{{description}}"){{^-last}}, {{/-last}}{{/scopes}}]{{/isOAuth}}){{^-last}}, {{/-last}}{{/authMethods}}]{{/hasAuthMethods}})
authorizations = [{{#authMethods}}Authorization(value = "{{name}}"{{#isOAuth}}, scopes = [{{#scopes}}AuthorizationScope(scope = "{{scope}}", description = "{{description}}"){{^-last}}, {{/-last}}{{/scopes}}]{{/isOAuth}}){{^-last}}, {{/-last}}{{/authMethods}}]{{/hasAuthMethods}}
)
@ApiResponses(
value = [{{#responses}}ApiResponse(code = {{{code}}}, message = "{{{message}}}"{{#baseType}}, response = {{{.}}}::class{{/baseType}}{{#containerType}}, responseContainer = "{{{.}}}"{{/containerType}}){{^-last}},{{/-last}}{{/responses}}]){{/swagger1AnnotationLibrary}}
value = [{{#responses}}ApiResponse(code = {{{code}}}, message = "{{#lambda.escapeDollar}}{{{message}}}{{/lambda.escapeDollar}}"{{#baseType}}, response = {{{.}}}::class{{/baseType}}{{#containerType}}, responseContainer = "{{{.}}}"{{/containerType}}){{^-last}},{{/-last}}{{/responses}}]
){{/swagger1AnnotationLibrary}}
@RequestMapping(
method = [RequestMethod.{{httpMethod}}],
value = [PATH_{{#lambda.uppercase}}{{#lambda.snakecase}}{{{operationId}}}{{/lambda.snakecase}}{{/lambda.uppercase}} /* "{{#lambdaEscapeInNormalString}}{{{path}}}{{/lambdaEscapeInNormalString}}" */]{{#singleContentTypes}}{{#hasProduces}},
value = [PATH_{{#lambda.uppercase}}{{#lambda.snakecase}}{{{operationId}}}{{/lambda.snakecase}}{{/lambda.uppercase}} /* "{{{path}}}" */]{{#singleContentTypes}}{{#hasProduces}},
produces = [{{#vendorExtensions.x-accepts}}"{{{.}}}"{{^-last}}, {{/-last}}{{/vendorExtensions.x-accepts}}]{{/hasProduces}}{{#hasConsumes}},
consumes = "{{{vendorExtensions.x-content-type}}}"{{/hasConsumes}}{{/singleContentTypes}}{{^singleContentTypes}}{{#hasProduces}},
produces = [{{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}}]{{/hasProduces}}{{#hasConsumes}},
Expand All @@ -111,7 +113,7 @@ class {{classname}}Controller({{#serviceInterface}}@Autowired(required = true) v
const val BASE_PATH: String = "{{=<% %>=}}<%contextPath%><%={{ }}=%>"
{{/useRequestMappingOnController}}
{{#operation}}
const val PATH_{{#lambda.uppercase}}{{#lambda.snakecase}}{{{operationId}}}{{/lambda.snakecase}}{{/lambda.uppercase}}: String = "{{{path}}}"
const val PATH_{{#lambda.uppercase}}{{#lambda.snakecase}}{{{operationId}}}{{/lambda.snakecase}}{{/lambda.uppercase}}: String = "{{#lambdaEscapeInNormalString}}{{{path}}}{{/lambdaEscapeInNormalString}}"
{{/operation}}
}
}
Expand Down
Loading
Loading