diff --git a/docs/generators/java-camel.md b/docs/generators/java-camel.md index 1c7efa14ec8..58520d7461c 100644 --- a/docs/generators/java-camel.md +++ b/docs/generators/java-camel.md @@ -124,7 +124,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |x-operation-extra-annotation|List of custom annotations to be added to operation|OPERATION|null |x-spring-paginated|Add org.springframework.data.domain.Pageable to controller method. Can be used to handle page & size query parameters|OPERATION|false |x-version-param|Marker property that tells that this parameter would be used for endpoint versioning. Applicable for headers & query params. true/false|OPERATION_PARAMETER|null -|x-pattern-message|Add this property whenever you need to customize the invalidation error message for the regex pattern of a variable|FIELD|null +|x-pattern-message|Add this property whenever you need to customize the invalidation error message for the regex pattern of a variable|FIELD, OPERATION_PARAMETER|null ## IMPORT MAPPING diff --git a/docs/generators/spring.md b/docs/generators/spring.md index 6ae3b647ac6..d026204231a 100644 --- a/docs/generators/spring.md +++ b/docs/generators/spring.md @@ -117,7 +117,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |x-operation-extra-annotation|List of custom annotations to be added to operation|OPERATION|null |x-spring-paginated|Add org.springframework.data.domain.Pageable to controller method. Can be used to handle page & size query parameters|OPERATION|false |x-version-param|Marker property that tells that this parameter would be used for endpoint versioning. Applicable for headers & query params. true/false|OPERATION_PARAMETER|null -|x-pattern-message|Add this property whenever you need to customize the invalidation error message for the regex pattern of a variable|FIELD|null +|x-pattern-message|Add this property whenever you need to customize the invalidation error message for the regex pattern of a variable|FIELD, OPERATION_PARAMETER|null ## IMPORT MAPPING diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index d61bd1f19db..4c10d78a9ef 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -5121,6 +5121,9 @@ public class DefaultCodegen implements CodegenConfig { if (parameter.getExtensions() != null && !parameter.getExtensions().isEmpty()) { codegenParameter.vendorExtensions.putAll(parameter.getExtensions()); } + if (parameter.getSchema() != null && parameter.getSchema().getExtensions() != null && !parameter.getSchema().getExtensions().isEmpty()) { + codegenParameter.vendorExtensions.putAll(parameter.getSchema().getExtensions()); + } Schema parameterSchema; diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/VendorExtension.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/VendorExtension.java index 0b1a91a11d6..c9b285475ec 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/VendorExtension.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/VendorExtension.java @@ -2,6 +2,7 @@ package org.openapitools.codegen; import lombok.Getter; +import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -21,7 +22,7 @@ import java.util.List; X_FIELD_EXTRA_ANNOTATION("x-field-extra-annotation", ExtensionLevel.FIELD, "List of custom annotations to be added to property", null), X_OPERATION_EXTRA_ANNOTATION("x-operation-extra-annotation", ExtensionLevel.OPERATION, "List of custom annotations to be added to operation", null), X_VERSION_PARAM("x-version-param", ExtensionLevel.OPERATION_PARAMETER, "Marker property that tells that this parameter would be used for endpoint versioning. Applicable for headers & query params. true/false", null), - X_PATTERN_MESSAGE("x-pattern-message", ExtensionLevel.FIELD, "Add this property whenever you need to customize the invalidation error message for the regex pattern of a variable", null), + X_PATTERN_MESSAGE("x-pattern-message", Arrays.asList(ExtensionLevel.FIELD, ExtensionLevel.OPERATION_PARAMETER), "Add this property whenever you need to customize the invalidation error message for the regex pattern of a variable", null), ; private final String name; diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java index 495a5f153c4..a32101a09cd 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java @@ -3148,6 +3148,61 @@ public class SpringCodegenTest { )); } + @Test + public void testXPatternMessage_issue18959() throws IOException { + File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); + output.deleteOnExit(); + + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/issue_18959.yaml"); + final SpringCodegen codegen = new SpringCodegen(); + codegen.setOpenAPI(openAPI); + codegen.setOutputDir(output.getAbsolutePath()); + + codegen.additionalProperties().put(SpringCodegen.DATE_LIBRARY, "java8-localdatetime"); + codegen.additionalProperties().put(INTERFACE_ONLY, "true"); + codegen.additionalProperties().put(USE_RESPONSE_ENTITY, "false"); + codegen.additionalProperties().put(DELEGATE_PATTERN, "true"); + codegen.additionalProperties().put(USE_BEANVALIDATION, "true"); + codegen.additionalProperties().put(PERFORM_BEANVALIDATION, "true"); + codegen.additionalProperties().put(REQUEST_MAPPING_OPTION, "api_interface"); + + ClientOptInput input = new ClientOptInput(); + input.openAPI(openAPI); + input.config(codegen); + + DefaultGenerator generator = new DefaultGenerator(); + generator.setGenerateMetadata(false); // skip metadata generation + + Map files = generator.opts(input).generate().stream() + .collect(Collectors.toMap(File::getName, Function.identity())); + + JavaFileAssert javaFileAssert = JavaFileAssert.assertThat(files.get("TestApi.java")); + javaFileAssert + .assertMethod("_postToTest") + .assertParameter("groupObj") + .assertParameterAnnotations() + .containsWithNameAndAttributes("Pattern", ImmutableMap.of( + "regexp", "\"[a-zA-Z]\"", + "message", "\"Only letters\"" + )) + .toParameter() + .toMethod() + .assertParameter("token") + .assertParameterAnnotations() + .containsWithNameAndAttributes("Pattern", ImmutableMap.of( + "regexp", "\"[0-9a-fA-F]\"", + "message", "\"Only numbers and letters a-f\"" + )) + .toParameter() + .toMethod() + .assertParameter("clientId") + .assertParameterAnnotations() + .containsWithNameAndAttributes("Pattern", ImmutableMap.of( + "regexp", "\"\\\\d\"", + "message", "\"Only numbers\"" + )); + } + @Test public void testEnumCaseInsensitive_issue8084() throws IOException { File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); diff --git a/modules/openapi-generator/src/test/resources/3_0/issue_18959.yaml b/modules/openapi-generator/src/test/resources/3_0/issue_18959.yaml new file mode 100644 index 00000000000..97905a4bbdd --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/issue_18959.yaml @@ -0,0 +1,63 @@ +openapi: 3.0.3 +info: + title: sample spec + version: 1.0.0 +paths: + /test/{groupObj}: + post: + summary: Post to test + description: '' + operationId: postToTest + parameters: + - $ref: '#/components/parameters/groupObj' + - $ref: '#/components/parameters/token' + - $ref: '#/components/parameters/clientId' + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ObjTest' + responses: + 201: + description: success +components: + parameters: + groupObj: + in: path + name: groupObj + required: true + schema: + type: string + pattern: "[a-zA-Z]" + x-pattern-message: "Only letters" + token: + in: query + name: token + required: true + schema: + type: string + pattern: "[0-9a-fA-F]" + x-pattern-message: "Only numbers and letters a-f" + clientId: + in: header + name: clientId + required: true + schema: + type: string + pattern: "\\d" + x-pattern-message: "Only numbers" + schemas: + ObjTest: + description: A model to return + type: object + properties: + field1: + type: integer + format: int64 + field2: + type: string + pattern: "\\w" + x-pattern-message: "Only letters, numbers and underscore" + field3: + type: string + pattern: "\\w"