diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenModel.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenModel.java index 41a3a176ab2a9..060b45d9eaa54 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenModel.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenModel.java @@ -251,6 +251,7 @@ public class CodegenModel implements IJsonSchemaValidationProperties { private String minimum; private String maximum; private String pattern; + private String originalPattern; private Number multipleOf; private CodegenProperty items; private CodegenProperty additionalProperties; @@ -363,7 +364,6 @@ public String getDiscriminatorName() { return discriminator == null ? null : discriminator.getPropertyName(); } - @Override public String getPattern() { return pattern; @@ -374,6 +374,16 @@ public void setPattern(String pattern) { this.pattern = pattern; } + @Override + public String getOriginalPattern() { + return originalPattern; + } + + @Override + public void setOriginalPattern(String originalPattern) { + this.originalPattern = originalPattern; + } + @Override public String getMaximum() { return maximum; @@ -966,6 +976,7 @@ public boolean equals(Object o) { Objects.equals(getMinimum(), that.getMinimum()) && Objects.equals(getMaximum(), that.getMaximum()) && Objects.equals(getPattern(), that.getPattern()) && + Objects.equals(getOriginalPattern(), that.getOriginalPattern()) && Objects.equals(getItems(), that.getItems()) && Objects.equals(getAdditionalProperties(), that.getAdditionalProperties()) && Objects.equals(getIsModel(), that.getIsModel()) && @@ -986,7 +997,7 @@ public int hashCode() { hasChildren, isMap, isOptional, isDeprecated, hasReadOnly, hasOnlyReadOnly, getExternalDocumentation(), getVendorExtensions(), getAdditionalPropertiesType(), getMaxProperties(), getMinProperties(), getUniqueItems(), getMaxItems(), getMinItems(), getMaxLength(), getMinLength(), getExclusiveMinimum(), getExclusiveMaximum(), getMinimum(), - getMaximum(), getPattern(), getMultipleOf(), getItems(), getAdditionalProperties(), getIsModel(), + getMaximum(), getPattern(), getOriginalPattern(), getMultipleOf(), getItems(), getAdditionalProperties(), getIsModel(), getAdditionalPropertiesIsAnyType(), hasDiscriminatorWithNonEmptyMapping, isAnyType, getComposedSchemas(), hasMultipleTypes, isDecimal, isUuid, isUri, requiredVarsMap, ref, uniqueItemsBoolean, schemaIsFromAdditionalProperties, isBooleanSchemaTrue, isBooleanSchemaFalse, @@ -1079,6 +1090,7 @@ public String toString() { sb.append(", minimum='").append(minimum).append('\''); sb.append(", maximum='").append(maximum).append('\''); sb.append(", pattern='").append(pattern).append('\''); + sb.append(", originalPattern='").append(originalPattern).append('\''); sb.append(", multipleOf='").append(multipleOf).append('\''); sb.append(", items='").append(items).append('\''); sb.append(", additionalProperties='").append(additionalProperties).append('\''); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenParameter.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenParameter.java index 0497bf49c55b6..c5275889b64fc 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenParameter.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenParameter.java @@ -108,6 +108,10 @@ public class CodegenParameter implements IJsonSchemaValidationProperties { * See JSON Schema Validation Spec, Section 6.3.3 */ public String pattern; + + /** Original pattern validation for strings, kept unchanged from OpenAPI schema */ + public String originalPattern; + /** * See JSON Schema Validation Spec, Section 6.4.1 */ @@ -173,6 +177,7 @@ public CodegenParameter copy() { output.maxLength = this.maxLength; output.minLength = this.minLength; output.pattern = this.pattern; + output.originalPattern = this.originalPattern; output.maxItems = this.maxItems; output.minItems = this.minItems; output.uniqueItems = this.uniqueItems; @@ -291,7 +296,7 @@ public int hashCode() { items, mostInnerItems, additionalProperties, vars, requiredVars, vendorExtensions, hasValidation, getMaxProperties(), getMinProperties(), isNullable, isDeprecated, required, getMaximum(), getExclusiveMaximum(), getMinimum(), getExclusiveMinimum(), getMaxLength(), getMinLength(), - getPattern(), getMaxItems(), getMinItems(), getUniqueItems(), contentType, multipleOf, isNull,isVoid, + getPattern(), getOriginalPattern(), getMaxItems(), getMinItems(), getUniqueItems(), contentType, multipleOf, isNull,isVoid, additionalPropertiesIsAnyType, hasVars, hasRequired, isShort, isUnboundedInteger, hasDiscriminatorWithNonEmptyMapping, composedSchemas, hasMultipleTypes, schema, content, requiredVarsMap, ref, uniqueItemsBoolean, schemaIsFromAdditionalProperties, @@ -398,6 +403,7 @@ public boolean equals(Object o) { Objects.equals(getMaxLength(), that.getMaxLength()) && Objects.equals(getMinLength(), that.getMinLength()) && Objects.equals(getPattern(), that.getPattern()) && + Objects.equals(getOriginalPattern(), that.getOriginalPattern()) && Objects.equals(getMaxItems(), that.getMaxItems()) && Objects.equals(getMinItems(), that.getMinItems()) && Objects.equals(contentType, that.contentType) && @@ -496,6 +502,7 @@ public String toString() { sb.append(", maxLength=").append(maxLength); sb.append(", minLength=").append(minLength); sb.append(", pattern='").append(pattern).append('\''); + sb.append(", originalPattern='").append(originalPattern).append('\''); sb.append(", maxItems=").append(maxItems); sb.append(", minItems=").append(minItems); sb.append(", uniqueItems=").append(uniqueItems); @@ -584,6 +591,16 @@ public void setPattern(String pattern) { this.pattern = pattern; } + @Override + public String getOriginalPattern() { + return originalPattern; + } + + @Override + public void setOriginalPattern(String originalPattern) { + this.originalPattern = originalPattern; + } + @Override public String getMaximum() { return maximum; diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenProperty.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenProperty.java index dddec1c620c66..e75c42acc98fd 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenProperty.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenProperty.java @@ -98,6 +98,10 @@ public class CodegenProperty implements Cloneable, IJsonSchemaValidationProperti * pattern validation for strings, see http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.2.3 */ public String pattern; + + /** Original pattern validation for strings, kept unchanged from OpenAPI schema */ + public String originalPattern; + /** * A free-form property to include an example of an instance for this schema. */ @@ -382,6 +386,16 @@ public void setPattern(String pattern) { this.pattern = pattern; } + @Override + public String getOriginalPattern() { + return originalPattern; + } + + @Override + public void setOriginalPattern(String originalPattern) { + this.originalPattern = originalPattern; + } + @Override public String getMinimum() { return minimum; @@ -986,6 +1000,7 @@ public String toString() { sb.append(", maxLength=").append(maxLength); sb.append(", minLength=").append(minLength); sb.append(", pattern='").append(pattern).append('\''); + sb.append(", originalPattern='").append(originalPattern).append('\''); sb.append(", example='").append(example).append('\''); sb.append(", jsonSchema='").append(jsonSchema).append('\''); sb.append(", minimum='").append(minimum).append('\''); @@ -1175,6 +1190,7 @@ public boolean equals(Object o) { Objects.equals(maxLength, that.maxLength) && Objects.equals(minLength, that.minLength) && Objects.equals(pattern, that.pattern) && + Objects.equals(originalPattern, that.originalPattern) && Objects.equals(example, that.example) && Objects.equals(jsonSchema, that.jsonSchema) && Objects.equals(minimum, that.minimum) && @@ -1206,7 +1222,7 @@ public int hashCode() { return Objects.hash(openApiType, baseName, complexType, getter, setter, description, dataType, datatypeWithEnum, dataFormat, name, min, max, defaultValue, defaultValueWithParam, baseType, containerType, containerTypeMapped, title, unescapedDescription, - maxLength, minLength, pattern, example, jsonSchema, minimum, maximum, + maxLength, minLength, pattern, originalPattern, example, jsonSchema, minimum, maximum, exclusiveMinimum, exclusiveMaximum, required, deprecated, hasMoreNonReadOnly, isPrimitiveType, isModel, isContainer, isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isDecimal, isByteArray, isBinary, isFile, diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenResponse.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenResponse.java index 9c8dc08aaa5f5..7419bd2f7f9aa 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenResponse.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenResponse.java @@ -86,6 +86,7 @@ public class CodegenResponse implements IJsonSchemaValidationProperties { private String minimum; private String maximum; public String pattern; + public String originalPattern; public Number multipleOf; public CodegenProperty items; public CodegenProperty additionalProperties; @@ -113,7 +114,7 @@ public int hashCode() { isMap, isOptional, isArray, isBinary, isFile, schema, jsonSchema, vendorExtensions, items, additionalProperties, vars, requiredVars, isNull, isVoid, hasValidation, isShort, isUnboundedInteger, getMaxProperties(), getMinProperties(), uniqueItems, getMaxItems(), getMinItems(), getMaxLength(), - getMinLength(), exclusiveMinimum, exclusiveMaximum, getMinimum(), getMaximum(), getPattern(), + getMinLength(), exclusiveMinimum, exclusiveMaximum, getMinimum(), getMaximum(), getPattern(), getOriginalPattern(), is1xx, is2xx, is3xx, is4xx, is5xx, additionalPropertiesIsAnyType, hasVars, hasRequired, hasDiscriminatorWithNonEmptyMapping, composedSchemas, hasMultipleTypes, responseHeaders, content, requiredVarsMap, ref, uniqueItemsBoolean, schemaIsFromAdditionalProperties); @@ -200,6 +201,7 @@ public boolean equals(Object o) { Objects.equals(getMinimum(), that.getMinimum()) && Objects.equals(getMaximum(), that.getMaximum()) && Objects.equals(getPattern(), that.getPattern()) && + Objects.equals(getOriginalPattern(), that.getOriginalPattern()) && Objects.equals(getMultipleOf(), that.getMultipleOf()); } @@ -264,6 +266,16 @@ public void setPattern(String pattern) { this.pattern = pattern; } + @Override + public String getOriginalPattern() { + return originalPattern; + } + + @Override + public void setOriginalPattern(String originalPattern) { + this.originalPattern = originalPattern; + } + @Override public String getMaximum() { return maximum; @@ -616,6 +628,7 @@ public String toString() { sb.append(", minimum='").append(minimum).append('\''); sb.append(", maximum='").append(maximum).append('\''); sb.append(", pattern='").append(pattern).append('\''); + sb.append(", originalPattern='").append(originalPattern).append('\''); sb.append(", multipleOf='").append(multipleOf).append('\''); sb.append(", items='").append(items).append('\''); sb.append(", additionalProperties='").append(additionalProperties).append('\''); 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 d8b577c93caee..787dcd3976899 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 @@ -4893,6 +4893,7 @@ public CodegenResponse fromResponse(String responseCode, ApiResponse response) { ModelUtils.syncValidationProperties(responseSchema, r); if (responseSchema.getPattern() != null) { r.setPattern(toRegularExpression(responseSchema.getPattern())); + r.setOriginalPattern(responseSchema.getPattern()); } CodegenProperty cp = fromProperty("response", responseSchema, false); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/IJsonSchemaValidationProperties.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/IJsonSchemaValidationProperties.java index 47fef0eddf5f8..b56ee6fc2f766 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/IJsonSchemaValidationProperties.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/IJsonSchemaValidationProperties.java @@ -29,6 +29,10 @@ public interface IJsonSchemaValidationProperties { void setPattern(String pattern); + String getOriginalPattern(); + + void setOriginalPattern(String originalPattern); + String getMaximum(); void setMaximum(String maximum); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractGoCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractGoCodegen.java index 0167338cc05ba..71bba66ed19ad 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractGoCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractGoCodegen.java @@ -787,29 +787,24 @@ public ModelsMap postProcessModels(ModelsMap objs) { } if (cp.pattern != null) { - LOGGER.info("Received pattern: {}", cp.pattern); - - // Pattern might be enclosed into /.../ that aren't wished. Remove them. - String p = cp.pattern; - - if (cp.pattern.startsWith("/") && cp.pattern.endsWith("/")) { - p = cp.pattern.substring(1, cp.pattern.length() - 1); - } - - String regexp = String.format(Locale.getDefault(), "regexp=%s", p); - String validate = String.format(Locale.getDefault(), "validate:\"%s\"", regexp); + String regexp = String.format(Locale.getDefault(), "regexp=%s", cp.originalPattern); // Replace backtick by \\x60, if found - if (validate.contains("`")) { - validate = validate.replace("`", "\\x60"); + if (regexp.contains("`")) { + regexp = regexp.replace("`", "\\x60"); } // Escape comma - if (validate.contains(",")) { - validate = validate.replace(",", "\\\\,"); + if (regexp.contains(",")) { + regexp = regexp.replace(",", "\\\\,"); + } + + // as the double quotes will be included in a string, ".......".....", they should be escaped once: ".....\"...." + if (regexp.contains("\"")) { + regexp = regexp.replace("\"", "\\\","); } - LOGGER.info("validate clause: {}", validate); + String validate = String.format(Locale.getDefault(), "validate:\"%s\"", regexp); cp.vendorExtensions.put(X_GO_CUSTOM_TAG, validate); } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptFetchClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptFetchClientCodegen.java index 69a0f3e80317c..ee65b500d3b93 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptFetchClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptFetchClientCodegen.java @@ -1564,6 +1564,7 @@ public ExtendedCodegenModel(CodegenModel cm) { this.setMinimum(cm.getMinimum()); this.setMaximum(cm.getMaximum()); this.setPattern(cm.getPattern()); + this.setOriginalPattern(cm.getOriginalPattern()); this.setMultipleOf(cm.getMultipleOf()); this.setItems(cm.getItems()); this.setAdditionalProperties(cm.getAdditionalProperties()); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java index c0a6b6acf7872..c5cd7e3616265 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java @@ -1838,6 +1838,8 @@ public static void syncValidationProperties(Schema schema, IJsonSchemaValidation String pattern = schema.getPattern(); if (pattern != null) vSB.withPattern(); + String originalPattern = pattern; + BigDecimal multipleOf = schema.getMultipleOf(); if (multipleOf != null) vSB.withMultipleOf(); @@ -1867,7 +1869,7 @@ public static void syncValidationProperties(Schema schema, IJsonSchemaValidation logWarnMessagesForIneffectiveValidations(new LinkedHashSet(setValidations), schema, SchemaValidations.OBJECT_VALIDATIONS); } else if (isStringSchema(schema)) { if (minLength != null || maxLength != null || pattern != null) - setStringValidations(minLength, maxLength, pattern, target); + setStringValidations(minLength, maxLength, pattern, originalPattern, target); if (isDecimalSchema(schema)) { if (multipleOf != null || minimum != null || maximum != null || exclusiveMinimum != null || exclusiveMaximum != null) setNumericValidations(schema, multipleOf, minimum, maximum, exclusiveMinimum, exclusiveMaximum, target); @@ -1886,7 +1888,7 @@ public static void syncValidationProperties(Schema schema, IJsonSchemaValidation // anyType can have any validations set on it setArrayValidations(minItems, maxItems, uniqueItems, target); setObjectValidations(minProperties, maxProperties, target); - setStringValidations(minLength, maxLength, pattern, target); + setStringValidations(minLength, maxLength, pattern, originalPattern, target); setNumericValidations(schema, multipleOf, minimum, maximum, exclusiveMinimum, exclusiveMaximum, target); } @@ -1906,10 +1908,11 @@ private static void setObjectValidations(Integer minProperties, Integer maxPrope if (maxProperties != null) target.setMaxProperties(maxProperties); } - private static void setStringValidations(Integer minLength, Integer maxLength, String pattern, IJsonSchemaValidationProperties target) { + private static void setStringValidations(Integer minLength, Integer maxLength, String pattern, String originalPattern, IJsonSchemaValidationProperties target) { if (minLength != null) target.setMinLength(minLength); if (maxLength != null) target.setMaxLength(maxLength); if (pattern != null) target.setPattern(pattern); + if (originalPattern != null) target.setOriginalPattern(originalPattern); } private static void setNumericValidations(Schema schema, BigDecimal multipleOf, BigDecimal minimum, BigDecimal maximum, Boolean exclusiveMinimum, Boolean exclusiveMaximum, IJsonSchemaValidationProperties target) { diff --git a/modules/openapi-generator/src/test/resources/3_0/issue_20079_go_regex_wrongly_translated.yaml b/modules/openapi-generator/src/test/resources/3_0/issue_20079_go_regex_wrongly_translated.yaml index fdb3b00a16d6c..fefa28b239f5d 100644 --- a/modules/openapi-generator/src/test/resources/3_0/issue_20079_go_regex_wrongly_translated.yaml +++ b/modules/openapi-generator/src/test/resources/3_0/issue_20079_go_regex_wrongly_translated.yaml @@ -27,5 +27,6 @@ components: pattern: "^[0-9]{2,}$" name: + # A very long and complex regex type: string - pattern: "^/0-9$" + pattern: "^[ !'&\"()*+,-./0-9:;<=>;?A-Z_a-z[]{}|^@#~]+`$"