From 681bf7aacaa370afbbad61b4ce35e6af8bb62cab Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Wed, 25 Mar 2020 10:01:40 +0100 Subject: [PATCH 1/8] HV-1756 Fix variable names in translations --- .../hibernate/validator/ValidationMessages_es.properties | 4 ++-- .../hibernate/validator/ValidationMessages_ko.properties | 8 ++++---- .../validator/ValidationMessages_mn_MN.properties | 2 +- .../hibernate/validator/ValidationMessages_tr.properties | 2 +- .../hibernate/validator/ValidationMessages_uk.properties | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_es.properties b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_es.properties index cea34f85f2..3c8b4d891a 100644 --- a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_es.properties +++ b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_es.properties @@ -49,5 +49,5 @@ org.hibernate.validator.constraints.pl.REGON.message = n\u00FAmer org.hibernate.validator.constraints.pl.NIP.message = n\u00FAmero de identificaci\u00F3n VAT (NIP) inv\u00E1lido org.hibernate.validator.constraints.pl.PESEL.message = n\u00FAmero de identificaci\u00F3n nacional Polaco (PESEL) inv\u00E1lido -org.hibernate.validator.constraints.time.DurationMax.message = tiene que durar menos {inclusive == true ? ' o igual que' : ''}${days == 0 ? '' : days == 1 ? ' 1 d\u00EDa' : ' ' += days += ' d\u00EDs'}${hours == 0 ? '' : hours == 1 ? ' 1 hora' : ' ' += hours += ' horas'}${minutes == 0 ? '' : minutes == 1 ? ' 1 minuto' : ' ' += minutes += ' minutos'}${seconds == 0 ? '' : seconds == 1 ? ' 1 segundo' : ' ' += seconds += ' segundos'}${millis == 0 ? '' : millis == 1 ? ' 1 milisegundo' : ' ' += millis += ' milisegundos'}${nanos == 0 ? '' : nanos == 1 ? ' 1 nanosegundo' : ' ' += nanos += ' nanosegundos'} -org.hibernate.validator.constraints.time.DurationMin.message = tiene que durar mas {inclusive == true ? ' o igual que' : ''}${days == 0 ? '' : days == 1 ? ' 1 d\u00EDa' : ' ' += days += ' d\u00EDs'}${hours == 0 ? '' : hours == 1 ? ' 1 hora' : ' ' += hours += ' horas'}${minutes == 0 ? '' : minutes == 1 ? ' 1 minuto' : ' ' += minutes += ' minutos'}${seconds == 0 ? '' : seconds == 1 ? ' 1 segundo' : ' ' += seconds += ' segundos'}${millis == 0 ? '' : millis == 1 ? ' 1 milisegundo' : ' ' += millis += ' milisegundos'}${nanos == 0 ? '' : nanos == 1 ? ' 1 nanosegundo' : ' ' += nanos += ' nanosegundos'} +org.hibernate.validator.constraints.time.DurationMax.message = tiene que durar menos${inclusive == true ? ' o igual que' : ''}${days == 0 ? '' : days == 1 ? ' 1 d\u00EDa' : ' ' += days += ' d\u00EDs'}${hours == 0 ? '' : hours == 1 ? ' 1 hora' : ' ' += hours += ' horas'}${minutes == 0 ? '' : minutes == 1 ? ' 1 minuto' : ' ' += minutes += ' minutos'}${seconds == 0 ? '' : seconds == 1 ? ' 1 segundo' : ' ' += seconds += ' segundos'}${millis == 0 ? '' : millis == 1 ? ' 1 milisegundo' : ' ' += millis += ' milisegundos'}${nanos == 0 ? '' : nanos == 1 ? ' 1 nanosegundo' : ' ' += nanos += ' nanosegundos'} +org.hibernate.validator.constraints.time.DurationMin.message = tiene que durar mas${inclusive == true ? ' o igual que' : ''}${days == 0 ? '' : days == 1 ? ' 1 d\u00EDa' : ' ' += days += ' d\u00EDs'}${hours == 0 ? '' : hours == 1 ? ' 1 hora' : ' ' += hours += ' horas'}${minutes == 0 ? '' : minutes == 1 ? ' 1 minuto' : ' ' += minutes += ' minutos'}${seconds == 0 ? '' : seconds == 1 ? ' 1 segundo' : ' ' += seconds += ' segundos'}${millis == 0 ? '' : millis == 1 ? ' 1 milisegundo' : ' ' += millis += ' milisegundos'}${nanos == 0 ? '' : nanos == 1 ? ' 1 nanosegundo' : ' ' += nanos += ' nanosegundos'} diff --git a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_ko.properties b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_ko.properties index aa839b8366..5f00482d72 100644 --- a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_ko.properties +++ b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_ko.properties @@ -20,10 +20,10 @@ org.hibernate.validator.constraints.EAN.message = {type} \ubc14\ucf54\ub4dc\uac0 org.hibernate.validator.constraints.Email.message = \uc774\uba54\uc77c \uc8fc\uc18c\uac00 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. org.hibernate.validator.constraints.Length.message = \ubc18\ub4dc\uc2dc \ucd5c\uc18c\uac12 {min}\uacfc(\uc640) \ucd5c\ub300\uac12 {max} \uc0ac\uc774\uc758 \uae38\uc774\uc774\uc5b4\uc57c \ud569\ub2c8\ub2e4. org.hibernate.validator.constraints.CodePointLength.message = \ubc18\ub4dc\uc2dc \ucd5c\uc18c\uac12 {min}\uacfc(\uc640) \ucd5c\ub300\uac12 {max} \uc0ac\uc774\uc758 \uae38\uc774\uc774\uc5b4\uc57c \ud569\ub2c8\ub2e4. -org.hibernate.validator.constraints.LuhnCheck.message = ${value}\uc758 check digit\uac00 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. Luhn Modulo 10 checksum \uc624\ub958\uac00 \ubc1c\uc0dd\ud558\uc600\uc2b5\ub2c8\ub2e4. -org.hibernate.validator.constraints.Mod10Check.message = ${value}\uc758 check digit\uac00 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. Modulo 10 checksum \uc624\ub958\uac00 \ubc1c\uc0dd\ud558\uc600\uc2b5\ub2c8\ub2e4. -org.hibernate.validator.constraints.Mod11Check.message = ${value}\uc758 check digit\uac00 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. Modulo 11 checksum \uc624\ub958\uac00 \ubc1c\uc0dd\ud558\uc600\uc2b5\ub2c8\ub2e4. -org.hibernate.validator.constraints.ModCheck.message = ${value}\uc758 check digit\uac00 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. ${modType} checksum \uc624\ub958\uac00 \ubc1c\uc0dd\ud558\uc600\uc2b5\ub2c8\ub2e4. +org.hibernate.validator.constraints.LuhnCheck.message = ${validatedValue}\uc758 check digit\uac00 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. Luhn Modulo 10 checksum \uc624\ub958\uac00 \ubc1c\uc0dd\ud558\uc600\uc2b5\ub2c8\ub2e4. +org.hibernate.validator.constraints.Mod10Check.message = ${validatedValue}\uc758 check digit\uac00 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. Modulo 10 checksum \uc624\ub958\uac00 \ubc1c\uc0dd\ud558\uc600\uc2b5\ub2c8\ub2e4. +org.hibernate.validator.constraints.Mod11Check.message = ${validatedValue}\uc758 check digit\uac00 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. Modulo 11 checksum \uc624\ub958\uac00 \ubc1c\uc0dd\ud558\uc600\uc2b5\ub2c8\ub2e4. +org.hibernate.validator.constraints.ModCheck.message = ${validatedValue}\uc758 check digit\uac00 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. ${modType} checksum \uc624\ub958\uac00 \ubc1c\uc0dd\ud558\uc600\uc2b5\ub2c8\ub2e4. org.hibernate.validator.constraints.NotBlank.message = \ubc18\ub4dc\uc2dc \uac12\uc774 \uc874\uc7ac\ud558\uace0 \uacf5\ubc31 \ubb38\uc790\ub97c \uc81c\uc678\ud55c \uae38\uc774\uac00 0\ubcf4\ub2e4 \ucee4\uc57c \ud569\ub2c8\ub2e4. org.hibernate.validator.constraints.NotEmpty.message = \ubc18\ub4dc\uc2dc \uac12\uc774 \uc874\uc7ac\ud558\uace0 \uae38\uc774 \ud639\uc740 \ud06c\uae30\uac00 0\ubcf4\ub2e4 \ucee4\uc57c \ud569\ub2c8\ub2e4. org.hibernate.validator.constraints.ParametersScriptAssert.message = \uc2a4\ud06c\ub9bd\ud2b8 \ud45c\ud604\uc2dd "{script}"\uc758 \uacb0\uacfc\uac00 \ucc38(true)\uc774 \uc544\ub2d9\ub2c8\ub2e4. diff --git a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_mn_MN.properties b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_mn_MN.properties index 657ba34b99..0bc5e39713 100644 --- a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_mn_MN.properties +++ b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_mn_MN.properties @@ -2,7 +2,7 @@ javax.validation.constraints.AssertFalse.message = \u0425\u0443\u0434\u0430\u043 javax.validation.constraints.AssertTrue.message = \u04AE\u043D\u044D\u043D \u0431\u0430\u0439\u0445 \u0451\u0441\u0442\u043E\u0439 javax.validation.constraints.DecimalMax.message = {value}-\u0430\u0430\u0441 \u0431\u0430\u0433\u0430 \u0431\u0443\u044E\u0443 \u0442\u044D\u043D\u0446\u04AF\u04AF \u0431\u0430\u0439\u0445 \u0451\u0441\u0442\u043E\u0439 javax.validation.constraints.DecimalMin.message = {value}-\u0430\u0430\u0441 \u0438\u0445 \u0431\u0443\u044E\u0443 \u0442\u044D\u043D\u0446\u04AF\u04AF \u0431\u0430\u0439\u0445 \u0451\u0441\u0442\u043E\u0439 -javax.validation.constraints.Digits.message = \u0422\u043E\u043E\u043D \u0445\u044F\u0437\u0433\u0430\u0430\u0440\u0430\u0430\u0441 \u0445\u044D\u0442\u044D\u0440\u0441\u044D\u043D \u0431\u0430\u0439\u043D\u0430 (<{integerDigits} digits>.<{fractionalDigits} digits> \u0445\u043E\u043E\u0440\u043E\u043D\u0434 \u0431\u0430\u0439\u043D\u0430) +javax.validation.constraints.Digits.message = \u0422\u043E\u043E\u043D \u0445\u044F\u0437\u0433\u0430\u0430\u0440\u0430\u0430\u0441 \u0445\u044D\u0442\u044D\u0440\u0441\u044D\u043D \u0431\u0430\u0439\u043D\u0430 (<{integer} digits>.<{fraction} digits> \u0445\u043E\u043E\u0440\u043E\u043D\u0434 \u0431\u0430\u0439\u043D\u0430) javax.validation.constraints.Email.message = \u0411\u0443\u0440\u0443\u0443 \u0438-\u043C\u044D\u0439\u043B \u0445\u0430\u044F\u0433 \u0431\u0430\u0439\u043D\u0430 javax.validation.constraints.Future.message = \u0418\u0440\u044D\u044D\u0434\u04AF\u0439\u0434 \u0431\u0430\u0439\u0445 \u0451\u0441\u0442\u043E\u0439 javax.validation.constraints.Max.message = {value}-\u0430\u0430\u0441 \u0431\u0430\u0433\u0430 \u0431\u0443\u044E\u0443 \u0442\u044D\u043D\u0446\u04AF\u04AF \u0431\u0430\u0439\u0445 \u0451\u0441\u0442\u043E\u0439 diff --git a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_tr.properties b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_tr.properties index 37e7223d66..9b7691e11d 100644 --- a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_tr.properties +++ b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_tr.properties @@ -2,7 +2,7 @@ javax.validation.constraints.AssertFalse.message = teyit ba\u015Far\u0131s\u0131 javax.validation.constraints.AssertTrue.message = teyit ba\u015Far\u0131s\u0131z javax.validation.constraints.DecimalMax.message = '{value}' de\u011Ferinden k\u00FC\u00E7\u00FCk yada e\u015Fit olmal\u0131 javax.validation.constraints.DecimalMin.message = '{value}' de\u011Ferinden b\u00FCy\u00FCk yada e\u015Fit olmal\u0131 -javax.validation.constraints.Digits.message = s\u0131n\u0131rlar\u0131n d\u0131\u015F\u0131nda say\u0131sal de\u011Fer (beklenen <{integerDigits} basamak>.<{fractionalDigits} basamak>) +javax.validation.constraints.Digits.message = s\u0131n\u0131rlar\u0131n d\u0131\u015F\u0131nda say\u0131sal de\u011Fer (beklenen <{integer} basamak>.<{fraction} basamak>) javax.validation.constraints.Email.message = d\u00FCzg\u00FCn bi\u00E7imli bir e-posta adresi de\u011Fil! javax.validation.constraints.Future.message = ileri bir tarih olmal\u0131 javax.validation.constraints.Max.message = '{value}' de\u011Ferinden k\u00FC\u00E7\u00FCk yada e\u015Fit olmal\u0131 diff --git a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_uk.properties b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_uk.properties index fb4e559c68..cf201e4e33 100644 --- a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_uk.properties +++ b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_uk.properties @@ -50,4 +50,4 @@ org.hibernate.validator.constraints.pl.NIP.message = \u043d\u0435\u043f\u04 org.hibernate.validator.constraints.pl.PESEL.message = \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0438\u0439 \u043f\u043e\u043b\u044c\u0441\u043a\u0438\u0439 \u043d\u0430\u0446\u0456\u043e\u043d\u0430\u043b\u044c\u043d\u0438\u0439 \u0456\u0434\u0435\u043d\u0442\u0438\u0444\u0456\u043a\u0430\u0446\u0456\u0439\u043d\u0438\u0439 \u043d\u043e\u043c\u0435\u0440 (PESEL) org.hibernate.validator.constraints.time.DurationMax.message = \u043c\u0430\u0454 \u0431\u0443\u0442\u0438 \u043a\u043e\u0440\u043e\u0442\u0448\u0438\u0439${inclusive == true ? ' \u0430\u0431\u043e \u0440\u0456\u0432\u043d\u0438\u0439' : ''} \u0437\u0430${days == 0 ? '' : days == 1 ? ' 1 \u0434\u0435\u043d\u044c' : ' ' += days += ' \u0434\u043d\u0456\u0432'}${hours == 0 ? '' : hours == 1 ? ' 1 \u0433\u043e\u0434\u0438\u043d\u0430' : ' ' += hours += ' \u0433\u043e\u0434\u0438\u043d'}${minutes == 0 ? '' : minutes == 1 ? ' 1 \u0445\u0432\u0438\u043b\u0438\u043d\u0430' : ' ' += minutes += ' \u0445\u0432\u0438\u043b\u0438\u043d'}${seconds == 0 ? '' : seconds == 1 ? ' 1 \u0441\u0435\u043a\u0443\u043d\u0434\u0430' : ' ' += seconds += ' \u0441\u0435\u043a\u0443\u043d\u0434'}${millis == 0 ? '' : millis == 1 ? ' 1 \u043c\u0456\u043b\u0456\u0441\u0435\u043a\u0443\u043d\u0434\u0430' : ' ' += millis += ' \u043c\u0456\u043b\u0456\u0441\u0435\u043a\u0443\u043d\u0434'}${nanos == 0 ? '' : nanos == 1 ? ' 1 \u043d\u0430\u043d\u043e\u0441\u0435\u043a\u0443\u043d\u0434\u0430' : ' ' += nanos += ' \u043d\u0430\u043d\u043e\u0441\u0435\u043a\u0443\u043d\u0434'} -org.hibernate.validator.constraints.time.DurationMin.message = \u043c\u0430\u0454 \u0431\u0443\u0442\u0438 \u0434\u043e\u0432\u0448\u0438\u0439{inclusive == true ? ' \u0430\u0431\u043e \u0440\u0456\u0432\u043d\u0438\u0439' : ''} \u0437\u0430${days == 0 ? '' : days == 1 ? ' 1 \u0434\u0435\u043d\u044c' : ' ' += days += ' \u0434\u043d\u0456\u0432'}${hours == 0 ? '' : hours == 1 ? ' 1 \u0433\u043e\u0434\u0438\u043d\u0430' : ' ' += hours += ' \u0433\u043e\u0434\u0438\u043d'}${minutes == 0 ? '' : minutes == 1 ? ' 1 \u0445\u0432\u0438\u043b\u0438\u043d\u0430' : ' ' += minutes += ' \u0445\u0432\u0438\u043b\u0438\u043d'}${seconds == 0 ? '' : seconds == 1 ? ' 1 \u0441\u0435\u043a\u0443\u043d\u0434\u0430' : ' ' += seconds += ' \u0441\u0435\u043a\u0443\u043d\u0434'}${millis == 0 ? '' : millis == 1 ? ' 1 \u043c\u0456\u043b\u0456\u0441\u0435\u043a\u0443\u043d\u0434\u0430' : ' ' += millis += ' \u043c\u0456\u043b\u0456\u0441\u0435\u043a\u0443\u043d\u0434'}${nanos == 0 ? '' : nanos == 1 ? ' 1 \u043d\u0430\u043d\u043e\u0441\u0435\u043a\u0443\u043d\u0434\u0430' : ' ' += nanos += ' \u043d\u0430\u043d\u043e\u0441\u0435\u043a\u0443\u043d\u0434'} +org.hibernate.validator.constraints.time.DurationMin.message = \u043c\u0430\u0454 \u0431\u0443\u0442\u0438 \u0434\u043e\u0432\u0448\u0438\u0439${inclusive == true ? ' \u0430\u0431\u043e \u0440\u0456\u0432\u043d\u0438\u0439' : ''} \u0437\u0430${days == 0 ? '' : days == 1 ? ' 1 \u0434\u0435\u043d\u044c' : ' ' += days += ' \u0434\u043d\u0456\u0432'}${hours == 0 ? '' : hours == 1 ? ' 1 \u0433\u043e\u0434\u0438\u043d\u0430' : ' ' += hours += ' \u0433\u043e\u0434\u0438\u043d'}${minutes == 0 ? '' : minutes == 1 ? ' 1 \u0445\u0432\u0438\u043b\u0438\u043d\u0430' : ' ' += minutes += ' \u0445\u0432\u0438\u043b\u0438\u043d'}${seconds == 0 ? '' : seconds == 1 ? ' 1 \u0441\u0435\u043a\u0443\u043d\u0434\u0430' : ' ' += seconds += ' \u0441\u0435\u043a\u0443\u043d\u0434'}${millis == 0 ? '' : millis == 1 ? ' 1 \u043c\u0456\u043b\u0456\u0441\u0435\u043a\u0443\u043d\u0434\u0430' : ' ' += millis += ' \u043c\u0456\u043b\u0456\u0441\u0435\u043a\u0443\u043d\u0434'}${nanos == 0 ? '' : nanos == 1 ? ' 1 \u043d\u0430\u043d\u043e\u0441\u0435\u043a\u0443\u043d\u0434\u0430' : ' ' += nanos += ' \u043d\u0430\u043d\u043e\u0441\u0435\u043a\u0443\u043d\u0434'} From a70c0d600a41ea97187157bcf91bbc6fe6687726 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Fri, 31 Jan 2020 11:43:19 +0100 Subject: [PATCH 2/8] HV-1756 Add a test validating all the messages are properly interpolated --- .../MessagePropertiesTest.java | 367 ++++++++++++++++++ 1 file changed, 367 insertions(+) create mode 100644 engine/src/test/java/org/hibernate/validator/test/internal/constraintvalidators/MessagePropertiesTest.java diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/constraintvalidators/MessagePropertiesTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/constraintvalidators/MessagePropertiesTest.java new file mode 100644 index 0000000000..af52588cce --- /dev/null +++ b/engine/src/test/java/org/hibernate/validator/test/internal/constraintvalidators/MessagePropertiesTest.java @@ -0,0 +1,367 @@ +/* + * Hibernate Validator, declare and validate application constraints + * + * License: Apache License, Version 2.0 + * See the license.txt file in the root directory or . + */ +package org.hibernate.validator.test.internal.constraintvalidators; + +import static org.hibernate.validator.testutil.ConstraintViolationAssert.violationOf; + +import java.math.BigDecimal; +import java.time.Duration; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.Set; + +import javax.money.MonetaryAmount; +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import javax.validation.constraints.AssertFalse; +import javax.validation.constraints.AssertTrue; +import javax.validation.constraints.DecimalMax; +import javax.validation.constraints.DecimalMin; +import javax.validation.constraints.Digits; +import javax.validation.constraints.Email; +import javax.validation.constraints.Future; +import javax.validation.constraints.FutureOrPresent; +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.Negative; +import javax.validation.constraints.NegativeOrZero; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Null; +import javax.validation.constraints.Past; +import javax.validation.constraints.PastOrPresent; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Positive; +import javax.validation.constraints.PositiveOrZero; +import javax.validation.constraints.Size; + +import org.hibernate.validator.HibernateValidator; +import org.hibernate.validator.constraints.CodePointLength; +import org.hibernate.validator.constraints.CreditCardNumber; +import org.hibernate.validator.constraints.Currency; +import org.hibernate.validator.constraints.EAN; +import org.hibernate.validator.constraints.ISBN; +import org.hibernate.validator.constraints.Length; +import org.hibernate.validator.constraints.LuhnCheck; +import org.hibernate.validator.constraints.Mod10Check; +import org.hibernate.validator.constraints.Mod11Check; +import org.hibernate.validator.constraints.ModCheck; +import org.hibernate.validator.constraints.ParameterScriptAssert; +import org.hibernate.validator.constraints.Range; +import org.hibernate.validator.constraints.SafeHtml; +import org.hibernate.validator.constraints.ScriptAssert; +import org.hibernate.validator.constraints.URL; +import org.hibernate.validator.constraints.UniqueElements; +import org.hibernate.validator.constraints.br.CNPJ; +import org.hibernate.validator.constraints.br.CPF; +import org.hibernate.validator.constraints.br.TituloEleitoral; +import org.hibernate.validator.constraints.pl.NIP; +import org.hibernate.validator.constraints.pl.PESEL; +import org.hibernate.validator.constraints.pl.REGON; +import org.hibernate.validator.constraints.time.DurationMax; +import org.hibernate.validator.constraints.time.DurationMin; +import org.hibernate.validator.testutil.ConstraintViolationAssert; +import org.javamoney.moneta.Money; +import org.testng.annotations.Test; + +/** + * Test that all the messages of all the constraints are properly interpolated for all the supported locales. + * + * @author Guillaume Smet + */ +@SuppressWarnings("deprecation") +public class MessagePropertiesTest { + + private static final List ALL_SUPPORTED_LOCALES = Arrays.asList( + Locale.forLanguageTag( "ar" ), + Locale.forLanguageTag( "cs" ), + Locale.forLanguageTag( "da" ), + Locale.forLanguageTag( "de" ), + Locale.forLanguageTag( "en" ), + Locale.forLanguageTag( "es" ), + Locale.forLanguageTag( "fa" ), + Locale.forLanguageTag( "fr" ), + Locale.forLanguageTag( "hu" ), + Locale.forLanguageTag( "it" ), + Locale.forLanguageTag( "ja" ), + Locale.forLanguageTag( "ko" ), + Locale.forLanguageTag( "mn-MN" ), + Locale.forLanguageTag( "nl" ), + Locale.forLanguageTag( "pl" ), + Locale.forLanguageTag( "pt-BR" ), + Locale.forLanguageTag( "ro" ), + Locale.forLanguageTag( "ru" ), + Locale.forLanguageTag( "sk" ), + Locale.forLanguageTag( "tr" ), + Locale.forLanguageTag( "uk" ), + Locale.forLanguageTag( "zh-CN" ), + Locale.forLanguageTag( "zh-TW" ), + Locale.forLanguageTag( "zh" ) + ); + + @Test + public void testMessageProperties() throws NoSuchMethodException, SecurityException { + List invalidMessages = new ArrayList<>(); + + Locale defaultLocale = Locale.getDefault(); + + try { + for ( Locale locale : ALL_SUPPORTED_LOCALES ) { + Locale.setDefault( locale ); + + Validator validator = Validation.byProvider( HibernateValidator.class ) + .configure() + .buildValidatorFactory() + .getValidator(); + + Set> violations = validator.validate( new Bean() ); + + ConstraintViolationAssert.assertThat( violations ) + .containsOnlyViolations( + violationOf( AssertFalse.class ), + violationOf( AssertTrue.class ), + violationOf( DecimalMax.class ), + violationOf( DecimalMin.class ), + violationOf( Digits.class ), + violationOf( Email.class ), + violationOf( Future.class ), + violationOf( FutureOrPresent.class ), + violationOf( Max.class ), + violationOf( Min.class ), + violationOf( Negative.class ), + violationOf( NegativeOrZero.class ), + violationOf( NotBlank.class ), + violationOf( NotEmpty.class ), + violationOf( NotNull.class ), + violationOf( Null.class ), + violationOf( Past.class ), + violationOf( PastOrPresent.class ), + violationOf( Pattern.class ), + violationOf( Positive.class ), + violationOf( PositiveOrZero.class ), + violationOf( Size.class ), + violationOf( CreditCardNumber.class ), + violationOf( Currency.class ), + violationOf( EAN.class ), + violationOf( org.hibernate.validator.constraints.Email.class ), + violationOf( ISBN.class ), + violationOf( Length.class ), + violationOf( CodePointLength.class ), + violationOf( LuhnCheck.class ), + violationOf( Mod10Check.class ), + violationOf( Mod11Check.class ), + violationOf( ModCheck.class ), + violationOf( org.hibernate.validator.constraints.NotBlank.class ), + violationOf( org.hibernate.validator.constraints.NotEmpty.class ), + violationOf( Range.class ), + violationOf( SafeHtml.class ), + violationOf( UniqueElements.class ), + violationOf( URL.class ), + violationOf( CNPJ.class ), + violationOf( CPF.class ), + violationOf( TituloEleitoral.class ), + violationOf( REGON.class ), + violationOf( NIP.class ), + violationOf( PESEL.class ), + violationOf( DurationMax.class ), + violationOf( DurationMin.class ), + violationOf( ScriptAssert.class ) + ); + + collectInvalidMessages( locale, invalidMessages, violations ); + + Set> parameterScriptAssertBeanViolations = validator.forExecutables().validateParameters( + new ParameterScriptAssertBean(), ParameterScriptAssertBean.class.getDeclaredMethod( "doTest", boolean.class ), new Object[]{ false } ); + + ConstraintViolationAssert.assertThat( parameterScriptAssertBeanViolations ) + .containsOnlyViolations( + violationOf( ParameterScriptAssert.class ) ); + + collectInvalidMessages( locale, invalidMessages, parameterScriptAssertBeanViolations ); + } + + if ( !invalidMessages.isEmpty() ) { + throw new IllegalStateException( "Some messages are invalid:\n\t- " + String.join( "\n\t- ", invalidMessages ) + "\n" ); + } + } + finally { + Locale.setDefault( defaultLocale ); + } + } + + private void collectInvalidMessages(Locale locale, List invalidMessages, Set> violations) { + for ( ConstraintViolation violation : violations ) { + if ( violation.getMessage().contains( "{" ) ) { + invalidMessages.add( + "Message for constraint " + violation.getConstraintDescriptor().getAnnotation().annotationType() + " and locale " + locale + + " contains a curly brace: " + violation.getMessage() ); + } + } + } + + @ScriptAssert(lang = "groovy", script = "_this.scriptAssert") + private static class Bean { + + @AssertFalse + private boolean assertFalse = true; + + @AssertTrue + private boolean assertTrue = false; + + @DecimalMax("3") + private double decimalMax = 4; + + @DecimalMin("3") + private double decimalMin = 2; + + @Digits(integer = 1, fraction = 3) + private BigDecimal digits = BigDecimal.valueOf( 13333.3333f ); + + @Email + private String email = "invalid"; + + @Future + private LocalDate future = LocalDate.of( 2010, 10, 4 ); + + @FutureOrPresent + private LocalDate futureOrPresent = LocalDate.of( 2010, 10, 4 ); + + @Max(4) + private int max = 6; + + @Min(4) + private int min = 2; + + @Negative + private int negative = 4; + + @NegativeOrZero + private int negativeOrZero = 4; + + @NotBlank + private String notBlank = ""; + + @NotEmpty + private List notEmpty = Collections.emptyList(); + + @NotNull + private String notNull = null; + + @Null + private String nullConstraint = "not null"; + + @Past + private LocalDate past = LocalDate.of( 2890, 10, 4 ); + + @PastOrPresent + private LocalDate pastOrPresent = LocalDate.of( 2890, 10, 4 ); + + @Pattern(regexp = "[0-9]+") + private String pattern = "invalid"; + + @Positive + private int positive = -4; + + @PositiveOrZero + private int positiveOrZero = -4; + + @Size(min = 2, max = 4) + private String size = "666666"; + + @CreditCardNumber + private String creditCardNumber = "invalid"; + + @Currency("EUR") + private MonetaryAmount currency = Money.of( 1000f, "USD" ); + + @EAN + private String ean = "invalid"; + + @org.hibernate.validator.constraints.Email + private String hvEmail = "invalid"; + + @ISBN + private String isbn = "invalid"; + + @Length(min = 2, max = 4) + private String length = "666666"; + + @CodePointLength(min = 2, max = 4) + private String codePointLength = "666666"; + + @LuhnCheck + private String luhnCheck = "4"; + + @Mod10Check + private String mod10Check = "4"; + + @Mod11Check + private String mod11Check = "4"; + + @ModCheck(multiplier = 2, modType = ModCheck.ModType.MOD10) + private String modCheck = "4"; + + @org.hibernate.validator.constraints.NotBlank + private String hvNotBlank = ""; + + @org.hibernate.validator.constraints.NotEmpty + private List hvNotEmpty = Collections.emptyList(); + + @Range(min = 2, max = 4) + private int range = 6; + + @SafeHtml + private String safeHtml = ""; + + @UniqueElements + private List uniqueElements = Arrays.asList( "a", "a" ); + + @URL + private String url = "invalid"; + + @CNPJ + private String cnpj = "invalid"; + + @CPF + private String cpf = "invalid"; + + @TituloEleitoral + private String tituloEleitoral = "invalid"; + + @REGON + private String regon = "invalid"; + + @NIP + private String nip = "invalid"; + + @PESEL + private String pesel = "invalid"; + + @DurationMax(days = 4, hours = 4, minutes = 4, millis = 4, nanos = 4) + private Duration durationMax = Duration.ofDays( 8 ); + + @DurationMin(days = 4, hours = 4, minutes = 4, millis = 4, nanos = 4) + private Duration durationMin = Duration.ofDays( 2 ); + + @SuppressWarnings("unused") + private boolean scriptAssert = false; + } + + private static class ParameterScriptAssertBean { + + @ParameterScriptAssert(lang = "groovy", script = "test") + public boolean doTest(boolean test) { + return test; + } + } +} From 243420ffe84e0d5386aea85018d88c5a92c255b2 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Fri, 31 Jan 2020 11:43:06 +0100 Subject: [PATCH 3/8] HV-1756 Be less verbose in test logging --- .../java/org/hibernate/validator/ValidationMessages.java | 4 ++-- engine/src/test/resources/log4j.properties | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/engine/src/test/java/org/hibernate/validator/ValidationMessages.java b/engine/src/test/java/org/hibernate/validator/ValidationMessages.java index 8da94713cd..91281345d5 100644 --- a/engine/src/test/java/org/hibernate/validator/ValidationMessages.java +++ b/engine/src/test/java/org/hibernate/validator/ValidationMessages.java @@ -34,9 +34,9 @@ public class ValidationMessages extends ResourceBundle { public ValidationMessages() throws Exception { - log.info( "For test purposes are we proxying the built-in messages!" ); + log.debug( "For test purposes we are proxying the built-in messages!" ); addTestPropertiesToBundle(); - log.infof( "Adding the following properties to default properties %s", messages ); + log.debugf( "Adding the following properties to default properties %s", messages ); loadDefaultValidationProperties(); } diff --git a/engine/src/test/resources/log4j.properties b/engine/src/test/resources/log4j.properties index 6e7112b594..78c71c612a 100644 --- a/engine/src/test/resources/log4j.properties +++ b/engine/src/test/resources/log4j.properties @@ -18,9 +18,9 @@ log4j.appender.socket.locationInfo=true ### set log levels - for more verbose logging change 'info' to 'debug' ### -log4j.rootLogger=debug, stdout +log4j.rootLogger=info, stdout -log4j.logger.org.hibernate.validator.internal.engine.ValidatorImpl=trace +#log4j.logger.org.hibernate.validator.internal.engine.ValidatorImpl=trace #log4j.logger.org.hibernate.validator.internal.engine.resolver.JPATraversableResolver=trace #log4j.logger.org.hibernate.validatorengine.ConstraintTree=trace -log4j.logger.org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator=info +#log4j.logger.org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator=info From a892674d1fd64cf8d6517b5e57d64d15683590a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yoann=20Rodi=C3=A8re?= Date: Wed, 25 Mar 2020 09:53:10 +0100 Subject: [PATCH 4/8] HV-1758 Remove extra $ characters in built-in contraint messages "{modType}" is evaluated to "MOD10" for example, so with the extra $ we were getting "$MOD10" in interpolated messages, instead of just "MOD10". --- .../org/hibernate/validator/ValidationMessages.properties | 2 +- .../org/hibernate/validator/ValidationMessages_es.properties | 2 +- .../org/hibernate/validator/ValidationMessages_fa.properties | 2 +- .../org/hibernate/validator/ValidationMessages_fr.properties | 2 +- .../org/hibernate/validator/ValidationMessages_ko.properties | 2 +- .../org/hibernate/validator/ValidationMessages_nl.properties | 2 +- .../org/hibernate/validator/ValidationMessages_pt_BR.properties | 2 +- .../org/hibernate/validator/ValidationMessages_ru.properties | 2 +- .../org/hibernate/validator/ValidationMessages_sk.properties | 2 +- .../org/hibernate/validator/ValidationMessages_uk.properties | 2 +- .../org/hibernate/validator/ValidationMessages_zh_CN.properties | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/engine/src/main/resources/org/hibernate/validator/ValidationMessages.properties b/engine/src/main/resources/org/hibernate/validator/ValidationMessages.properties index 2cb1354faa..c3064d0066 100644 --- a/engine/src/main/resources/org/hibernate/validator/ValidationMessages.properties +++ b/engine/src/main/resources/org/hibernate/validator/ValidationMessages.properties @@ -31,7 +31,7 @@ org.hibernate.validator.constraints.CodePointLength.message = length mus org.hibernate.validator.constraints.LuhnCheck.message = the check digit for ${validatedValue} is invalid, Luhn Modulo 10 checksum failed org.hibernate.validator.constraints.Mod10Check.message = the check digit for ${validatedValue} is invalid, Modulo 10 checksum failed org.hibernate.validator.constraints.Mod11Check.message = the check digit for ${validatedValue} is invalid, Modulo 11 checksum failed -org.hibernate.validator.constraints.ModCheck.message = the check digit for ${validatedValue} is invalid, ${modType} checksum failed +org.hibernate.validator.constraints.ModCheck.message = the check digit for ${validatedValue} is invalid, {modType} checksum failed org.hibernate.validator.constraints.NotBlank.message = may not be empty org.hibernate.validator.constraints.NotEmpty.message = may not be empty org.hibernate.validator.constraints.ParametersScriptAssert.message = script expression "{script}" didn't evaluate to true diff --git a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_es.properties b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_es.properties index 3c8b4d891a..d65b4f79bc 100644 --- a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_es.properties +++ b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_es.properties @@ -31,7 +31,7 @@ org.hibernate.validator.constraints.CodePointLength.message = la longitu org.hibernate.validator.constraints.LuhnCheck.message = el d\u00EDgito de verificaci\u00F3n para ${validatedValue} es inv\u00E1lido, la suma de verificaci\u00F3n Luhn M\u00F3dulo 10 fall\u00F3 org.hibernate.validator.constraints.Mod10Check.message = el d\u00EDgito de verificaci\u00F3n para ${validatedValue} es inv\u00E1lido, la suma de verificaci\u00F3n M\u00F3dulo 10 fall\u00F3 org.hibernate.validator.constraints.Mod11Check.message = el d\u00EDgito de verificaci\u00F3n para ${validatedValue} es inv\u00E1lido, la suma de verificaci\u00F3n M\u00F3dulo 11 fall\u00F3 -org.hibernate.validator.constraints.ModCheck.message = el d\u00EDgito de verificaci\u00F3n para ${validatedValue} es inv\u00E1lido, la suma de verificaci\u00F3n ${modType} fall\u00F3 +org.hibernate.validator.constraints.ModCheck.message = el d\u00EDgito de verificaci\u00F3n para ${validatedValue} es inv\u00E1lido, la suma de verificaci\u00F3n {modType} fall\u00F3 org.hibernate.validator.constraints.NotBlank.message = no puede estar vac\u00EDo org.hibernate.validator.constraints.NotEmpty.message = no puede estar vac\u00EDo org.hibernate.validator.constraints.ParametersScriptAssert.message = la expresi\u00F3n "{script}" no se ha evaluado como verdadera diff --git a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_fa.properties b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_fa.properties index f86a395bb1..373db2a5ae 100644 --- a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_fa.properties +++ b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_fa.properties @@ -30,7 +30,7 @@ org.hibernate.validator.constraints.CodePointLength.message = \u0637\u06 org.hibernate.validator.constraints.LuhnCheck.message = \u0645\u0642\u062F\u0627\u0631 ${validatedValue} \u0628\u0627 Luhn Modulo 10 \u0647\u0645\u062E\u0648\u0627\u0646\u06CC \u0646\u062F\u0627\u0631\u062F org.hibernate.validator.constraints.Mod10Check.message = \u0645\u0642\u062F\u0627\u0631 ${validatedValue} \u0628\u0627 Modulo 10 \u0647\u0645\u062E\u0648\u0627\u0646\u06CC \u0646\u062F\u0627\u0631\u062F org.hibernate.validator.constraints.Mod11Check.message = \u0645\u0642\u062F\u0627\u0631 ${validatedValue} \u0628\u0627 Modulo 11 \u0647\u0645\u062E\u0648\u0627\u0646\u06CC \u0646\u062F\u0627\u0631\u062F -org.hibernate.validator.constraints.ModCheck.message = \u0645\u0642\u062F\u0627\u0631 ${validatedValue} \u0628\u0627 ${modType} \u0647\u0645\u062E\u0648\u0627\u0646\u06CC \u0646\u062F\u0627\u0631\u062F +org.hibernate.validator.constraints.ModCheck.message = \u0645\u0642\u062F\u0627\u0631 ${validatedValue} \u0628\u0627 {modType} \u0647\u0645\u062E\u0648\u0627\u0646\u06CC \u0646\u062F\u0627\u0631\u062F org.hibernate.validator.constraints.NotBlank.message = \u0645\u0642\u062F\u0627\u0631 \u0646\u0628\u0627\u06CC\u062F \u062E\u0627\u0644\u06CC \u0628\u0627\u0634\u062F org.hibernate.validator.constraints.NotEmpty.message = \u0645\u0642\u062F\u0627\u0631 \u0646\u0628\u0627\u06CC\u062F \u062E\u0627\u0644\u06CC \u0628\u0627\u0634\u062F org.hibernate.validator.constraints.ParametersScriptAssert.message = \u0627\u0633\u06A9\u0631\u06CC\u067E\u062A "{script}" \u0645\u0642\u062F\u0627\u0631 \u062F\u0631\u0633\u062A \u0628\u0631\u0646\u0645\u06CC\u06AF\u0631\u062F\u0627\u0646\u062F diff --git a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_fr.properties b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_fr.properties index 675fb5251a..a5f327deb0 100644 --- a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_fr.properties +++ b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_fr.properties @@ -31,7 +31,7 @@ org.hibernate.validator.constraints.CodePointLength.message = la longueur doit org.hibernate.validator.constraints.LuhnCheck.message = le chiffre de contr\u00F4le pour ${validatedValue} est invalide, le contr\u00F4le Luhn Modulo 10 a \u00E9chou\u00E9 org.hibernate.validator.constraints.Mod10Check.message = le chiffre de contr\u00F4le pour ${validatedValue} est invalide, le contr\u00F4le Modulo 10 a \u00E9chou\u00E9 org.hibernate.validator.constraints.Mod11Check.message = le chiffre de contr\u00F4le pour ${validatedValue} est invalide, le contr\u00F4le Modulo 11 a \u00E9chou\u00E9 -org.hibernate.validator.constraints.ModCheck.message = le chiffre de contr\u00F4le pour ${validatedValue} est invalide, le contr\u00F4le ${modType} a \u00E9chou\u00E9 +org.hibernate.validator.constraints.ModCheck.message = le chiffre de contr\u00F4le pour ${validatedValue} est invalide, le contr\u00F4le {modType} a \u00E9chou\u00E9 org.hibernate.validator.constraints.NotBlank.message = ne peut pas \u00EAtre vide org.hibernate.validator.constraints.NotEmpty.message = ne peut pas \u00EAtre vide org.hibernate.validator.constraints.ParametersScriptAssert.message = le script "{script}" n'a pas \u00E9t\u00E9 \u00E9valu\u00E9 \u00E0 vrai diff --git a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_ko.properties b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_ko.properties index 5f00482d72..2ad755c13a 100644 --- a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_ko.properties +++ b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_ko.properties @@ -23,7 +23,7 @@ org.hibernate.validator.constraints.CodePointLength.message = \ubc18\ub4dc\uc2dc org.hibernate.validator.constraints.LuhnCheck.message = ${validatedValue}\uc758 check digit\uac00 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. Luhn Modulo 10 checksum \uc624\ub958\uac00 \ubc1c\uc0dd\ud558\uc600\uc2b5\ub2c8\ub2e4. org.hibernate.validator.constraints.Mod10Check.message = ${validatedValue}\uc758 check digit\uac00 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. Modulo 10 checksum \uc624\ub958\uac00 \ubc1c\uc0dd\ud558\uc600\uc2b5\ub2c8\ub2e4. org.hibernate.validator.constraints.Mod11Check.message = ${validatedValue}\uc758 check digit\uac00 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. Modulo 11 checksum \uc624\ub958\uac00 \ubc1c\uc0dd\ud558\uc600\uc2b5\ub2c8\ub2e4. -org.hibernate.validator.constraints.ModCheck.message = ${validatedValue}\uc758 check digit\uac00 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. ${modType} checksum \uc624\ub958\uac00 \ubc1c\uc0dd\ud558\uc600\uc2b5\ub2c8\ub2e4. +org.hibernate.validator.constraints.ModCheck.message = ${validatedValue}\uc758 check digit\uac00 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. {modType} checksum \uc624\ub958\uac00 \ubc1c\uc0dd\ud558\uc600\uc2b5\ub2c8\ub2e4. org.hibernate.validator.constraints.NotBlank.message = \ubc18\ub4dc\uc2dc \uac12\uc774 \uc874\uc7ac\ud558\uace0 \uacf5\ubc31 \ubb38\uc790\ub97c \uc81c\uc678\ud55c \uae38\uc774\uac00 0\ubcf4\ub2e4 \ucee4\uc57c \ud569\ub2c8\ub2e4. org.hibernate.validator.constraints.NotEmpty.message = \ubc18\ub4dc\uc2dc \uac12\uc774 \uc874\uc7ac\ud558\uace0 \uae38\uc774 \ud639\uc740 \ud06c\uae30\uac00 0\ubcf4\ub2e4 \ucee4\uc57c \ud569\ub2c8\ub2e4. org.hibernate.validator.constraints.ParametersScriptAssert.message = \uc2a4\ud06c\ub9bd\ud2b8 \ud45c\ud604\uc2dd "{script}"\uc758 \uacb0\uacfc\uac00 \ucc38(true)\uc774 \uc544\ub2d9\ub2c8\ub2e4. diff --git a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_nl.properties b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_nl.properties index 526f3cfb62..0fb8f5ca5f 100644 --- a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_nl.properties +++ b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_nl.properties @@ -31,7 +31,7 @@ org.hibernate.validator.constraints.CodePointLength.message = moet tusse org.hibernate.validator.constraints.LuhnCheck.message = het controlecijfer voor ${validatedValue} is ongeldig, Luhn Modulo 10 checksum mislukt org.hibernate.validator.constraints.Mod10Check.message = het controlecijfer voor ${validatedValue} is ongeldig, Modulo 10 checksum mislukt org.hibernate.validator.constraints.Mod11Check.message = het controlecijfer voor ${validatedValue} is ongeldig, Modulo 11 checksum mislukt -org.hibernate.validator.constraints.ModCheck.message = het controlecijfer voor ${validatedValue} is ongeldig, ${modType} checksum mislukt +org.hibernate.validator.constraints.ModCheck.message = het controlecijfer voor ${validatedValue} is ongeldig, {modType} checksum mislukt org.hibernate.validator.constraints.NotBlank.message = mag niet onbeschreven zijn org.hibernate.validator.constraints.NotEmpty.message = mag niet leeg zijn org.hibernate.validator.constraints.ParametersScriptAssert.message = scriptexpressie "{script}" is ongeldig diff --git a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_pt_BR.properties b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_pt_BR.properties index 14861f48f2..9f5e4ce5b4 100644 --- a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_pt_BR.properties +++ b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_pt_BR.properties @@ -29,7 +29,7 @@ org.hibernate.validator.constraints.CodePointLength.message = tamanho deve e org.hibernate.validator.constraints.LuhnCheck.message = digito verificador para ${validatedValue} \u00E9 inv\u00E1lido, verifica\u00E7\u00E3o M\u00F3dulo 10 de Luhn falhou org.hibernate.validator.constraints.Mod10Check.message = digito verificador para ${validatedValue} \u00E9 inv\u00E1lido, verifica\u00E7\u00E3o M\u00F3dulo 10 falhou org.hibernate.validator.constraints.Mod11Check.message = digito verificador para ${validatedValue} \u00E9 inv\u00E1lido, verifica\u00E7\u00E3o M\u00F3dulo 10 falhou -org.hibernate.validator.constraints.ModCheck.message = digito verificador para ${validatedValue} \u00E9 inv\u00E1lido, verifica\u00E7\u00E3o ${modType} falhou +org.hibernate.validator.constraints.ModCheck.message = digito verificador para ${validatedValue} \u00E9 inv\u00E1lido, verifica\u00E7\u00E3o {modType} falhou org.hibernate.validator.constraints.NotBlank.message = n\u00E3o pode estar em branco org.hibernate.validator.constraints.NotEmpty.message = n\u00E3o pode estar vazio org.hibernate.validator.constraints.ParametersScriptAssert.message = o script "{script}" n\u00E3o retornou verdadeiro diff --git a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_ru.properties b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_ru.properties index 6c89c64ab8..9d3f174e89 100644 --- a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_ru.properties +++ b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_ru.properties @@ -22,7 +22,7 @@ org.hibernate.validator.constraints.CodePointLength.message = \u0434\u04 org.hibernate.validator.constraints.LuhnCheck.message = \u043A\u043E\u043D\u0442\u0440\u043E\u043B\u044C\u043D\u0430\u044F \u0446\u0438\u0444\u0440\u0430 \u0434\u043B\u044F ${validatedValue} \u043D\u0435\u0432\u0435\u0440\u043D\u0430, \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 \u043F\u043E \u0430\u043B\u0433\u043E\u0440\u0438\u0442\u043C\u0443 \u041B\u0443\u043D\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D\u0430 \u0441 \u043E\u0448\u0438\u0431\u043A\u043E\u0439 org.hibernate.validator.constraints.Mod10Check.message = \u043A\u043E\u043D\u0442\u0440\u043E\u043B\u044C\u043D\u0430\u044F \u0446\u0438\u0444\u0440\u0430 \u0434\u043B\u044F ${validatedValue} \u043D\u0435\u0432\u0435\u0440\u043D\u0430, \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 \u043F\u043E \u0430\u043B\u0433\u043E\u0440\u0438\u0442\u043C\u0443 Mod10 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D\u0430 \u0441 \u043E\u0448\u0438\u0431\u043A\u043E\u0439 org.hibernate.validator.constraints.Mod11Check.message = \u043A\u043E\u043D\u0442\u0440\u043E\u043B\u044C\u043D\u0430\u044F \u0446\u0438\u0444\u0440\u0430 \u0434\u043B\u044F ${validatedValue} \u043D\u0435\u0432\u0435\u0440\u043D\u0430, \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 \u043F\u043E \u0430\u043B\u0433\u043E\u0440\u0438\u0442\u043C\u0443 Mod11 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D\u0430 \u0441 \u043E\u0448\u0438\u0431\u043A\u043E\u0439 -org.hibernate.validator.constraints.ModCheck.message = \u043A\u043E\u043D\u0442\u0440\u043E\u043B\u044C\u043D\u0430\u044F \u0446\u0438\u0444\u0440\u0430 \u0434\u043B\u044F ${validatedValue} \u043D\u0435\u0432\u0435\u0440\u043D\u0430, \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 \u043F\u043E ${modType} \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D\u0430 \u0441 \u043E\u0448\u0438\u0431\u043A\u043E\u0439 +org.hibernate.validator.constraints.ModCheck.message = \u043A\u043E\u043D\u0442\u0440\u043E\u043B\u044C\u043D\u0430\u044F \u0446\u0438\u0444\u0440\u0430 \u0434\u043B\u044F ${validatedValue} \u043D\u0435\u0432\u0435\u0440\u043D\u0430, \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 \u043F\u043E {modType} \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D\u0430 \u0441 \u043E\u0448\u0438\u0431\u043A\u043E\u0439 org.hibernate.validator.constraints.NotBlank.message = \u043D\u0435 \u043C\u043E\u0436\u0435\u0442 \u0431\u044B\u0442\u044C \u043F\u0443\u0441\u0442\u043E org.hibernate.validator.constraints.NotEmpty.message = \u043D\u0435 \u043C\u043E\u0436\u0435\u0442 \u0431\u044B\u0442\u044C \u043F\u0443\u0441\u0442\u043E org.hibernate.validator.constraints.ParametersScriptAssert.message = \u0432\u044B\u0440\u0430\u0436\u0435\u043D\u0438\u0435 "{script}" \u043D\u0435 \u044F\u0432\u043B\u044F\u0435\u0442\u0441\u044F \u0438\u0441\u0442\u0438\u043D\u043D\u044B\u043C diff --git a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_sk.properties b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_sk.properties index 1268340cd9..2380b475f8 100644 --- a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_sk.properties +++ b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_sk.properties @@ -23,7 +23,7 @@ org.hibernate.validator.constraints.CodePointLength.message = d\u013a\u0 org.hibernate.validator.constraints.LuhnCheck.message = kontroln\u00e1 \u010d\u00edslica pre ${validatedValue} nie je spr\u00e1vna, kontroln\u00fd s\u00fa\u010det Luhn Modulo 10 zlyhal org.hibernate.validator.constraints.Mod10Check.message = kontroln\u00e1 \u010d\u00edslica pre ${validatedValue} nie je spr\u00e1vna, kontroln\u00fd s\u00fa\u010det Modulo 10 zlyhal org.hibernate.validator.constraints.Mod11Check.message = kontroln\u00e1 \u010d\u00edslica pre ${validatedValue} nie je spr\u00e1vna, kontroln\u00fd s\u00fa\u010det Modulo 11 zlyhal -org.hibernate.validator.constraints.ModCheck.message = kontroln\u00e1 \u010d\u00edslica pre ${validatedValue} nie je spr\u00e1vna, kontroln\u00fd s\u00fa\u010det ${modType} zlyhal +org.hibernate.validator.constraints.ModCheck.message = kontroln\u00e1 \u010d\u00edslica pre ${validatedValue} nie je spr\u00e1vna, kontroln\u00fd s\u00fa\u010det {modType} zlyhal org.hibernate.validator.constraints.NotBlank.message = nem\u00f4\u017ee by\u0165 pr\u00e1zdne org.hibernate.validator.constraints.NotEmpty.message = nem\u00f4\u017ee by\u0165 pr\u00e1zdne org.hibernate.validator.constraints.ParametersScriptAssert.message = skriptovac\u00ed v\u00fdraz "{script}" nebol vyhodnoten\u00fd na \u00e1no diff --git a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_uk.properties b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_uk.properties index cf201e4e33..18d1416159 100644 --- a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_uk.properties +++ b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_uk.properties @@ -31,7 +31,7 @@ org.hibernate.validator.constraints.CodePointLength.message = \u0434\u04 org.hibernate.validator.constraints.LuhnCheck.message = \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c\u043d\u0430 \u0446\u0438\u0444\u0440\u0430 \u0434\u043b\u044f ${validatedValue}, \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430 \u0437\u0430 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u043c \u041b\u0443\u043d\u0430 \u0437\u0430\u043a\u0456\u043d\u0447\u0438\u043b\u0430\u0441\u044c \u0437 \u043f\u043e\u043c\u0438\u043b\u043a\u043e\u044e org.hibernate.validator.constraints.Mod10Check.message = \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c\u043d\u0430 \u0446\u0438\u0444\u0440\u0430 \u0434\u043b\u044f ${validatedValue}, \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430 \u0437\u0430 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u043c Mod10 \u0437\u0430\u043a\u0456\u043d\u0447\u0438\u043b\u0430\u0441\u044c \u0437 \u043f\u043e\u043c\u0438\u043b\u043a\u043e\u044e org.hibernate.validator.constraints.Mod11Check.message = \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c\u043d\u0430 \u0446\u0438\u0444\u0440\u0430 \u0434\u043b\u044f ${validatedValue}, \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430 \u0437\u0430 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u043c Mod11 \u0437\u0430\u043a\u0456\u043d\u0447\u0438\u043b\u0430\u0441\u044c \u0437 \u043f\u043e\u043c\u0438\u043b\u043a\u043e\u044e -org.hibernate.validator.constraints.ModCheck.message = \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c\u043d\u0430 \u0446\u0438\u0444\u0440\u0430 \u0434\u043b\u044f ${validatedValue}, \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430 \u0437\u0430 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u043c ${modType} \u0437\u0430\u043a\u0456\u043d\u0447\u0438\u043b\u0430\u0441\u044c \u0437 \u043f\u043e\u043c\u0438\u043b\u043a\u043e\u044e +org.hibernate.validator.constraints.ModCheck.message = \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c\u043d\u0430 \u0446\u0438\u0444\u0440\u0430 \u0434\u043b\u044f ${validatedValue}, \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430 \u0437\u0430 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u043c {modType} \u0437\u0430\u043a\u0456\u043d\u0447\u0438\u043b\u0430\u0441\u044c \u0437 \u043f\u043e\u043c\u0438\u043b\u043a\u043e\u044e org.hibernate.validator.constraints.NotBlank.message = \u043d\u0435 \u043c\u043e\u0436\u0435 \u0431\u0443\u0442\u0438 \u043f\u0443\u0441\u0442\u0438\u043c org.hibernate.validator.constraints.NotEmpty.message = \u043d\u0435 \u043c\u043e\u0436\u0435 \u0431\u0443\u0442\u0438 \u043f\u043e\u0440\u043e\u0436\u043d\u0456\u043c org.hibernate.validator.constraints.ParametersScriptAssert.message = \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432\u0438\u0439 \u0432\u0438\u0440\u0430\u0437 "{script}" \u043d\u0435 \u0454 \u0456\u0441\u0442\u0438\u043d\u043d\u0438\u043c diff --git a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_zh_CN.properties b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_zh_CN.properties index dba87b580d..b2a75318fe 100644 --- a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_zh_CN.properties +++ b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_zh_CN.properties @@ -30,7 +30,7 @@ org.hibernate.validator.constraints.CodePointLength.message = \u957f\u5e org.hibernate.validator.constraints.LuhnCheck.message = ${validatedValue}\u7684\u6821\u9a8c\u7801\u4e0d\u5408\u6cd5, Luhn\u6a2110\u6821\u9a8c\u548c\u4e0d\u5339\u914d org.hibernate.validator.constraints.Mod10Check.message = ${validatedValue}\u7684\u6821\u9a8c\u7801\u4e0d\u5408\u6cd5, \u6a2110\u6821\u9a8c\u548c\u4e0d\u5339\u914d org.hibernate.validator.constraints.Mod11Check.message = ${validatedValue}\u7684\u6821\u9a8c\u7801\u4e0d\u5408\u6cd5, \u6a2111\u6821\u9a8c\u548c\u4e0d\u5339\u914d -org.hibernate.validator.constraints.ModCheck.message = ${validatedValue}\u7684\u6821\u9a8c\u7801\u4e0d\u5408\u6cd5, ${modType}\u6821\u9a8c\u548c\u4e0d\u5339\u914d +org.hibernate.validator.constraints.ModCheck.message = ${validatedValue}\u7684\u6821\u9a8c\u7801\u4e0d\u5408\u6cd5, {modType}\u6821\u9a8c\u548c\u4e0d\u5339\u914d org.hibernate.validator.constraints.NotBlank.message = \u4e0d\u80fd\u4e3a\u7a7a org.hibernate.validator.constraints.NotEmpty.message = \u4e0d\u80fd\u4e3a\u7a7a org.hibernate.validator.constraints.ParametersScriptAssert.message = \u6267\u884c\u811a\u672c\u8868\u8fbe\u5f0f"{script}"\u6ca1\u6709\u8fd4\u56de\u671f\u671b\u7ed3\u679c From 919190e8c563bf52c0d845c3995bfacaf7ef05c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yoann=20Rodi=C3=A8re?= Date: Tue, 25 Feb 2020 15:00:02 +0100 Subject: [PATCH 5/8] HV-1758 Check for un-interpolated dollar signs in MessagePropertiesTest --- .../internal/constraintvalidators/MessagePropertiesTest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/constraintvalidators/MessagePropertiesTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/constraintvalidators/MessagePropertiesTest.java index af52588cce..38d1aee63f 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/constraintvalidators/MessagePropertiesTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/constraintvalidators/MessagePropertiesTest.java @@ -206,6 +206,11 @@ private void collectInvalidMessages(Locale locale, List invalidMessages, "Message for constraint " + violation.getConstraintDescriptor().getAnnotation().annotationType() + " and locale " + locale + " contains a curly brace: " + violation.getMessage() ); } + if ( violation.getMessage().contains( "$" ) ) { + invalidMessages.add( + "Message for constraint " + violation.getConstraintDescriptor().getAnnotation().annotationType() + " and locale " + locale + + " contains a dollar sign: " + violation.getMessage() ); + } } } From 94e1eef087f7b0b99788b181a8f63d698a8c1010 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Wed, 25 Mar 2020 10:17:31 +0100 Subject: [PATCH 6/8] HV-1755 Backport BeanMetaDataClassNormalizer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Yoann Rodière --- .../HibernateValidatorConfiguration.java | 13 ++ .../internal/engine/ConfigurationImpl.java | 19 +++ .../internal/engine/ValidatorFactoryImpl.java | 9 ++ .../metadata/BeanMetaDataManager.java | 21 ++- .../DefaultBeanMetaDataClassNormalizer.java | 24 ++++ .../metadata/BeanMetaDataClassNormalizer.java | 39 ++++++ ...actoryBeanMetadataClassNormalizerTest.java | 120 ++++++++++++++++++ .../internal/engine/path/PathImplTest.java | 3 +- .../metadata/BeanMetaDataManagerTest.java | 2 + .../aggregated/ExecutableMetaDataTest.java | 2 + .../aggregated/ParameterMetaDataTest.java | 3 + .../aggregated/PropertyMetaDataTest.java | 2 + 12 files changed, 250 insertions(+), 7 deletions(-) create mode 100644 engine/src/main/java/org/hibernate/validator/internal/metadata/DefaultBeanMetaDataClassNormalizer.java create mode 100644 engine/src/main/java/org/hibernate/validator/metadata/BeanMetaDataClassNormalizer.java create mode 100644 engine/src/test/java/org/hibernate/validator/test/internal/engine/ValidatorFactoryBeanMetadataClassNormalizerTest.java diff --git a/engine/src/main/java/org/hibernate/validator/HibernateValidatorConfiguration.java b/engine/src/main/java/org/hibernate/validator/HibernateValidatorConfiguration.java index 45773d3949..8d2e6d1ed5 100644 --- a/engine/src/main/java/org/hibernate/validator/HibernateValidatorConfiguration.java +++ b/engine/src/main/java/org/hibernate/validator/HibernateValidatorConfiguration.java @@ -20,6 +20,7 @@ import org.hibernate.validator.cfg.ConstraintMapping; import org.hibernate.validator.constraints.ParameterScriptAssert; import org.hibernate.validator.constraints.ScriptAssert; +import org.hibernate.validator.metadata.BeanMetaDataClassNormalizer; import org.hibernate.validator.spi.resourceloading.ResourceBundleLocator; import org.hibernate.validator.spi.scripting.ScriptEvaluator; import org.hibernate.validator.spi.scripting.ScriptEvaluatorFactory; @@ -311,4 +312,16 @@ public interface HibernateValidatorConfiguration extends Configuration optionalMetaDataProviders, MethodValidationConfiguration methodValidationConfiguration) { @@ -125,6 +129,7 @@ public BeanMetaDataManager(ConstraintHelper constraintHelper, this.typeResolutionHelper = typeResolutionHelper; this.valueExtractorManager = valueExtractorManager; this.parameterNameProvider = parameterNameProvider; + this.beanMetaDataClassNormalizer = beanMetaDataClassNormalizer; this.validationOrderGenerator = validationOrderGenerator; this.metaDataProviders = newArrayList(); @@ -152,26 +157,30 @@ public BeanMetaDataManager(ConstraintHelper constraintHelper, this.metaDataProviders.add( defaultProvider ); } + // TODO Some of these casts from BeanMetadata to BeanMetadata may not be safe. + // Maybe we should return a wrapper around the BeanMetadata if the normalized class is different from beanClass? @SuppressWarnings("unchecked") public BeanMetaData getBeanMetaData(Class beanClass) { Contracts.assertNotNull( beanClass, MESSAGES.beanTypeCannotBeNull() ); + Class normalizedBeanClass = beanMetaDataClassNormalizer.normalize( beanClass ); + // First, let's do a simple lookup as it's the default case - BeanMetaData beanMetaData = (BeanMetaData) beanMetaDataCache.get( beanClass ); + BeanMetaData beanMetaData = (BeanMetaData) beanMetaDataCache.get( normalizedBeanClass ); if ( beanMetaData != null ) { - return beanMetaData; + return (BeanMetaData) beanMetaData; } - beanMetaData = createBeanMetaData( beanClass ); - BeanMetaData previousBeanMetaData = (BeanMetaData) beanMetaDataCache.putIfAbsent( beanClass, beanMetaData ); + beanMetaData = createBeanMetaData( normalizedBeanClass ); + BeanMetaData previousBeanMetaData = (BeanMetaData) beanMetaDataCache.putIfAbsent( normalizedBeanClass, beanMetaData ); // we return the previous value if not null if ( previousBeanMetaData != null ) { - return previousBeanMetaData; + return (BeanMetaData) previousBeanMetaData; } - return beanMetaData; + return (BeanMetaData) beanMetaData; } public void clear() { diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/DefaultBeanMetaDataClassNormalizer.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/DefaultBeanMetaDataClassNormalizer.java new file mode 100644 index 0000000000..14e6e40f37 --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/DefaultBeanMetaDataClassNormalizer.java @@ -0,0 +1,24 @@ +/* + * Hibernate Validator, declare and validate application constraints + * + * License: Apache License, Version 2.0 + * See the license.txt file in the root directory or . + */ +package org.hibernate.validator.internal.metadata; + +import org.hibernate.validator.metadata.BeanMetaDataClassNormalizer; + +/** + * The default implementation of {@link BeanMetaDataClassNormalizer}. + *

+ * Simply returns the provided class. + * + * @author Guillaume Smet + */ +public class DefaultBeanMetaDataClassNormalizer implements BeanMetaDataClassNormalizer { + + @Override + public Class normalize(Class beanClass) { + return beanClass; + } +} diff --git a/engine/src/main/java/org/hibernate/validator/metadata/BeanMetaDataClassNormalizer.java b/engine/src/main/java/org/hibernate/validator/metadata/BeanMetaDataClassNormalizer.java new file mode 100644 index 0000000000..d102783f2d --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/metadata/BeanMetaDataClassNormalizer.java @@ -0,0 +1,39 @@ +/* + * Hibernate Validator, declare and validate application constraints + * + * License: Apache License, Version 2.0 + * See the license.txt file in the root directory or . + */ +package org.hibernate.validator.metadata; + +import org.hibernate.validator.Incubating; + +/** + * Define how the validated class is normalized before being used as the key to get the bean metadata. + *

+ * In the case of the predefined scope validator factory, we have to register all the classes that will ever be + * validated. To validate method calls, frameworks usually generate proxies to intercept the calls. Such proxies might + * be hard to register in the predefined scope validator factory as they are generated code. + *

+ * This contract allows to normalize the class before obtaining the metadata from the + * {@code BeanMetaDataManager} so that we only have to register the original bean class and not the proxy + * class. + *

+ * Apart from avoiding the need to register the class, it also avoids generating unnecessary metadata for the proxy + * classes. + * + * @author Guillaume Smet + * @since 6.1 + */ +@Incubating +public interface BeanMetaDataClassNormalizer { + + /** + * Normalizes the provided class as the key used to get the bean metadata from the + * {@code BeanMetaDataManager}. + * + * @param beanClass the original bean class + * @return the normalized class + */ + Class normalize(Class beanClass); +} diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/engine/ValidatorFactoryBeanMetadataClassNormalizerTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/engine/ValidatorFactoryBeanMetadataClassNormalizerTest.java new file mode 100644 index 0000000000..33e930c256 --- /dev/null +++ b/engine/src/test/java/org/hibernate/validator/test/internal/engine/ValidatorFactoryBeanMetadataClassNormalizerTest.java @@ -0,0 +1,120 @@ +/* + * Hibernate Validator, declare and validate application constraints + * + * License: Apache License, Version 2.0 + * See the license.txt file in the root directory or . + */ +package org.hibernate.validator.test.internal.engine; + +import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertThat; +import static org.hibernate.validator.testutil.ConstraintViolationAssert.pathWith; +import static org.hibernate.validator.testutil.ConstraintViolationAssert.violationOf; + +import java.util.Arrays; +import java.util.List; +import java.util.Set; +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.ValidationException; +import javax.validation.Validator; +import javax.validation.ValidatorFactory; +import javax.validation.constraints.Email; +import javax.validation.valueextraction.Unwrapping; + +import org.hibernate.validator.HibernateValidator; +import org.hibernate.validator.internal.engine.ValidatorFactoryImpl; +import org.hibernate.validator.metadata.BeanMetaDataClassNormalizer; + +import org.testng.annotations.Test; + +/** + * Test for {@link ValidatorFactoryImpl}. + * + * @author Gunnar Morling + */ +public class ValidatorFactoryBeanMetadataClassNormalizerTest { + + @Test(expectedExceptions = ValidationException.class, + expectedExceptionsMessageRegExp = ".*No suitable value extractor found for type interface java.util.List.*") + public void testBeanMetaDataClassNormalizerNoNormalizer() throws NoSuchMethodException { + ValidatorFactory validatorFactory = Validation.byDefaultProvider() + .configure() + .buildValidatorFactory(); + + Validator validator = validatorFactory.getValidator(); + + // As the proxy defines invalid constraints (see BeanProxy), we expect this to fail + validator.forExecutables().validateParameters( + new BeanProxy(), BeanProxy.class.getMethod( "setEmails", List.class ), + new Object[] { Arrays.asList( "notAnEmail" ) } + ); + } + + @Test + public void testBeanMetaDataClassNormalizer() throws NoSuchMethodException { + ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class ) + .configure() + .beanMetaDataClassNormalizer( new MyProxyInterfaceBeanMetaDataClassNormalizer() ) + .buildValidatorFactory(); + + Validator validator = validatorFactory.getValidator(); + + Set> violations = validator.forExecutables().validateParameters( + new BeanProxy(), BeanProxy.class.getMethod( "setEmails", List.class ), + new Object[] { Arrays.asList( "notAnEmail" ) } + ); + + assertThat( violations ).containsOnlyViolations( + violationOf( Email.class ).withPropertyPath( + pathWith().method( "setEmails" ) + .parameter( "emails", 0 ) + .containerElement( "", true, null, 0, List.class, 0 ) + ) + ); + } + + private static class Bean { + + private List emails; + + public Bean() { + } + + public Bean(List emails) { + this.emails = emails; + } + + public List getEmails() { + return emails; + } + + public void setEmails(@Email(payload = Unwrapping.Unwrap.class) List emails) { + this.emails = emails; + } + } + + private interface MyProxyInterface { + } + + private static class MyProxyInterfaceBeanMetaDataClassNormalizer implements BeanMetaDataClassNormalizer { + + @Override + public Class normalize(Class beanClass) { + if ( MyProxyInterface.class.isAssignableFrom( beanClass ) ) { + return beanClass.getSuperclass(); + } + + return beanClass; + } + } + + private static class BeanProxy extends Bean implements MyProxyInterface { + // The proxy dropped the generics, but kept constraint annotations, + // which will cause trouble unless its metadata is ignored. + @Override + @SuppressWarnings("unchecked") + public void setEmails(@Email(payload = Unwrapping.Unwrap.class) List emails) { + super.setEmails( emails ); + } + } +} diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/engine/path/PathImplTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/engine/path/PathImplTest.java index 0c95be5ee2..86f3217fc8 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/engine/path/PathImplTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/engine/path/PathImplTest.java @@ -33,6 +33,7 @@ import org.hibernate.validator.internal.engine.path.PathImpl; import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager; import org.hibernate.validator.internal.metadata.BeanMetaDataManager; +import org.hibernate.validator.internal.metadata.DefaultBeanMetaDataClassNormalizer; import org.hibernate.validator.internal.metadata.aggregated.ExecutableMetaData; import org.hibernate.validator.internal.metadata.core.ConstraintHelper; import org.hibernate.validator.internal.metadata.provider.MetaDataProvider; @@ -40,7 +41,6 @@ import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; import org.hibernate.validator.internal.util.TypeResolutionHelper; import org.hibernate.validator.testutils.ValidatorUtil; - import org.testng.annotations.Test; /** @@ -197,6 +197,7 @@ public void testCreationOfExecutablePath() throws Exception { new TypeResolutionHelper(), new ExecutableParameterNameProvider( new DefaultParameterNameProvider() ), new ValueExtractorManager( Collections.emptySet() ), + new DefaultBeanMetaDataClassNormalizer(), new ValidationOrderGenerator(), Collections.emptyList(), new MethodValidationConfiguration.Builder().build() diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/metadata/BeanMetaDataManagerTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/metadata/BeanMetaDataManagerTest.java index 9b402186b8..8df70c9eff 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/metadata/BeanMetaDataManagerTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/metadata/BeanMetaDataManagerTest.java @@ -25,6 +25,7 @@ import org.hibernate.validator.internal.engine.groups.ValidationOrderGenerator; import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager; import org.hibernate.validator.internal.metadata.BeanMetaDataManager; +import org.hibernate.validator.internal.metadata.DefaultBeanMetaDataClassNormalizer; import org.hibernate.validator.internal.metadata.aggregated.BeanMetaData; import org.hibernate.validator.internal.metadata.aggregated.BeanMetaDataImpl; import org.hibernate.validator.internal.metadata.core.ConstraintHelper; @@ -56,6 +57,7 @@ public void setUpBeanMetaDataManager() { new TypeResolutionHelper(), new ExecutableParameterNameProvider( new DefaultParameterNameProvider() ), new ValueExtractorManager( Collections.emptySet() ), + new DefaultBeanMetaDataClassNormalizer(), new ValidationOrderGenerator(), Collections.emptyList(), new MethodValidationConfiguration.Builder().build() diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/metadata/aggregated/ExecutableMetaDataTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/metadata/aggregated/ExecutableMetaDataTest.java index e1a80396f4..e3a32774df 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/metadata/aggregated/ExecutableMetaDataTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/metadata/aggregated/ExecutableMetaDataTest.java @@ -26,6 +26,7 @@ import org.hibernate.validator.internal.engine.groups.ValidationOrderGenerator; import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager; import org.hibernate.validator.internal.metadata.BeanMetaDataManager; +import org.hibernate.validator.internal.metadata.DefaultBeanMetaDataClassNormalizer; import org.hibernate.validator.internal.metadata.aggregated.BeanMetaData; import org.hibernate.validator.internal.metadata.aggregated.ExecutableMetaData; import org.hibernate.validator.internal.metadata.core.ConstraintHelper; @@ -61,6 +62,7 @@ public void setupBeanMetaData() { new TypeResolutionHelper(), new ExecutableParameterNameProvider( new DefaultParameterNameProvider() ), new ValueExtractorManager( Collections.emptySet() ), + new DefaultBeanMetaDataClassNormalizer(), new ValidationOrderGenerator(), Collections.emptyList(), new MethodValidationConfiguration.Builder().build() diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/metadata/aggregated/ParameterMetaDataTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/metadata/aggregated/ParameterMetaDataTest.java index bccf0c208b..b18cdec1b0 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/metadata/aggregated/ParameterMetaDataTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/metadata/aggregated/ParameterMetaDataTest.java @@ -28,6 +28,7 @@ import org.hibernate.validator.internal.engine.groups.ValidationOrderGenerator; import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager; import org.hibernate.validator.internal.metadata.BeanMetaDataManager; +import org.hibernate.validator.internal.metadata.DefaultBeanMetaDataClassNormalizer; import org.hibernate.validator.internal.metadata.aggregated.BeanMetaData; import org.hibernate.validator.internal.metadata.aggregated.ExecutableMetaData; import org.hibernate.validator.internal.metadata.aggregated.ParameterMetaData; @@ -61,6 +62,7 @@ public void setupBeanMetaData() { new TypeResolutionHelper(), new ExecutableParameterNameProvider( new DefaultParameterNameProvider() ), new ValueExtractorManager( Collections.emptySet() ), + new DefaultBeanMetaDataClassNormalizer(), new ValidationOrderGenerator(), Collections.emptyList(), new MethodValidationConfiguration.Builder().build() @@ -131,6 +133,7 @@ public void parameterNameInInheritanceHierarchy() throws Exception { new TypeResolutionHelper(), new ExecutableParameterNameProvider( new SkewedParameterNameProvider() ), new ValueExtractorManager( Collections.emptySet() ), + new DefaultBeanMetaDataClassNormalizer(), new ValidationOrderGenerator(), Collections.emptyList(), new MethodValidationConfiguration.Builder().build() diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/metadata/aggregated/PropertyMetaDataTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/metadata/aggregated/PropertyMetaDataTest.java index fe2577ea2e..a595ed9c69 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/metadata/aggregated/PropertyMetaDataTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/metadata/aggregated/PropertyMetaDataTest.java @@ -21,6 +21,7 @@ import org.hibernate.validator.internal.engine.groups.ValidationOrderGenerator; import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager; import org.hibernate.validator.internal.metadata.BeanMetaDataManager; +import org.hibernate.validator.internal.metadata.DefaultBeanMetaDataClassNormalizer; import org.hibernate.validator.internal.metadata.aggregated.PropertyMetaData; import org.hibernate.validator.internal.metadata.core.ConstraintHelper; import org.hibernate.validator.internal.metadata.provider.MetaDataProvider; @@ -45,6 +46,7 @@ public void setupBeanMetaDataManager() { new TypeResolutionHelper(), new ExecutableParameterNameProvider( new DefaultParameterNameProvider() ), new ValueExtractorManager( Collections.emptySet() ), + new DefaultBeanMetaDataClassNormalizer(), new ValidationOrderGenerator(), Collections.emptyList(), new MethodValidationConfiguration.Builder().build() From 23f7d1c6ebd518d945fd167a360bde1a8514d099 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yoann=20Rodi=C3=A8re?= Date: Thu, 16 Jan 2020 17:14:44 +0100 Subject: [PATCH 7/8] HV-1755 Allow bean metadata class normalizers to be provided to the CDI extension --- .../cdi/internal/ValidatorFactoryBean.java | 21 +++++++++++++++++++ .../validator/cdi/spi/BeanNames.java | 16 ++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 cdi/src/main/java/org/hibernate/validator/cdi/spi/BeanNames.java diff --git a/cdi/src/main/java/org/hibernate/validator/cdi/internal/ValidatorFactoryBean.java b/cdi/src/main/java/org/hibernate/validator/cdi/internal/ValidatorFactoryBean.java index 342342f282..632a9e7750 100644 --- a/cdi/src/main/java/org/hibernate/validator/cdi/internal/ValidatorFactoryBean.java +++ b/cdi/src/main/java/org/hibernate/validator/cdi/internal/ValidatorFactoryBean.java @@ -22,6 +22,8 @@ import javax.enterprise.context.ApplicationScoped; import javax.enterprise.context.spi.CreationalContext; +import javax.enterprise.inject.Instance; +import javax.enterprise.inject.literal.NamedLiteral; import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.BeanManager; import javax.enterprise.inject.spi.InjectionPoint; @@ -37,12 +39,15 @@ import javax.validation.ValidatorFactory; import javax.validation.valueextraction.ValueExtractor; +import org.hibernate.validator.HibernateValidatorConfiguration; +import org.hibernate.validator.cdi.spi.BeanNames; import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorDescriptor; import org.hibernate.validator.internal.util.CollectionHelper; import org.hibernate.validator.internal.util.classhierarchy.ClassHierarchyHelper; import org.hibernate.validator.internal.util.privilegedactions.GetClassLoader; import org.hibernate.validator.internal.util.privilegedactions.GetInstancesFromServiceLoader; import org.hibernate.validator.internal.util.privilegedactions.LoadClass; +import org.hibernate.validator.metadata.BeanMetaDataClassNormalizer; /** * A {@link Bean} representing a {@link ValidatorFactory}. There is one instance of this type representing the default @@ -126,6 +131,22 @@ public ValidatorFactory create(CreationalContext ctx) { config.parameterNameProvider( createParameterNameProvider( config ) ); config.clockProvider( createClockProvider( config ) ); + if ( config instanceof HibernateValidatorConfiguration ) { + HibernateValidatorConfiguration hvConfig = (HibernateValidatorConfiguration) config; + Instance beanMetaDataClassNormalizerInstance = + beanManager.createInstance() + .select( + BeanMetaDataClassNormalizer.class, + NamedLiteral.of( BeanNames.BEAN_META_DATA_CLASS_NORMALIZER ) + ); + if ( beanMetaDataClassNormalizerInstance.isResolvable() ) { + BeanMetaDataClassNormalizer normalizer = beanMetaDataClassNormalizerInstance.get(); + destructibleResources.add( new DestructibleBeanInstance<>( beanManager, normalizer ) ); + + hvConfig.beanMetaDataClassNormalizer( normalizer ); + } + } + addValueExtractorBeans( config ); return config.buildValidatorFactory(); diff --git a/cdi/src/main/java/org/hibernate/validator/cdi/spi/BeanNames.java b/cdi/src/main/java/org/hibernate/validator/cdi/spi/BeanNames.java new file mode 100644 index 0000000000..cb9f1da7f5 --- /dev/null +++ b/cdi/src/main/java/org/hibernate/validator/cdi/spi/BeanNames.java @@ -0,0 +1,16 @@ +/* + * Hibernate Validator, declare and validate application constraints + * + * License: Apache License, Version 2.0 + * See the license.txt file in the root directory or . + */ +package org.hibernate.validator.cdi.spi; + +public final class BeanNames { + + private BeanNames() { + } + + public static final String BEAN_META_DATA_CLASS_NORMALIZER = "hibernate-validator-bean-meta-data-class-normalizer"; + +} From 40d51966f5a197dfee6b851e38a90f9946faabaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yoann=20Rodi=C3=A8re?= Date: Thu, 16 Jan 2020 18:12:50 +0100 Subject: [PATCH 8/8] HV-1755 Test bean metadata class normalizers provided to the CDI extension --- .../cdi/internal/ValidatorFactoryBean.java | 2 +- .../CustomProxy.java | 10 ++ ...ustomProxyBeanMetaDataClassNormalizer.java | 89 +++++++++++++++ ...anMetadataClassNormalizerCdiExtension.java | 18 ++++ ...ovidedBeanMetadataClassNormalizerTest.java | 102 ++++++++++++++++++ 5 files changed, 220 insertions(+), 1 deletion(-) create mode 100644 cdi/src/test/java/org/hibernate/validator/test/cdi/internal/beanmetadataclassnormalizer/CustomProxy.java create mode 100644 cdi/src/test/java/org/hibernate/validator/test/cdi/internal/beanmetadataclassnormalizer/CustomProxyBeanMetaDataClassNormalizer.java create mode 100644 cdi/src/test/java/org/hibernate/validator/test/cdi/internal/beanmetadataclassnormalizer/CustomProxyBeanMetadataClassNormalizerCdiExtension.java create mode 100644 cdi/src/test/java/org/hibernate/validator/test/cdi/internal/beanmetadataclassnormalizer/ExtensionProvidedBeanMetadataClassNormalizerTest.java diff --git a/cdi/src/main/java/org/hibernate/validator/cdi/internal/ValidatorFactoryBean.java b/cdi/src/main/java/org/hibernate/validator/cdi/internal/ValidatorFactoryBean.java index 632a9e7750..eec74f1042 100644 --- a/cdi/src/main/java/org/hibernate/validator/cdi/internal/ValidatorFactoryBean.java +++ b/cdi/src/main/java/org/hibernate/validator/cdi/internal/ValidatorFactoryBean.java @@ -142,7 +142,7 @@ public ValidatorFactory create(CreationalContext ctx) { if ( beanMetaDataClassNormalizerInstance.isResolvable() ) { BeanMetaDataClassNormalizer normalizer = beanMetaDataClassNormalizerInstance.get(); destructibleResources.add( new DestructibleBeanInstance<>( beanManager, normalizer ) ); - + hvConfig.beanMetaDataClassNormalizer( normalizer ); } } diff --git a/cdi/src/test/java/org/hibernate/validator/test/cdi/internal/beanmetadataclassnormalizer/CustomProxy.java b/cdi/src/test/java/org/hibernate/validator/test/cdi/internal/beanmetadataclassnormalizer/CustomProxy.java new file mode 100644 index 0000000000..5bb6b09212 --- /dev/null +++ b/cdi/src/test/java/org/hibernate/validator/test/cdi/internal/beanmetadataclassnormalizer/CustomProxy.java @@ -0,0 +1,10 @@ +/* + * Hibernate Validator, declare and validate application constraints + * + * License: Apache License, Version 2.0 + * See the license.txt file in the root directory or . + */ +package org.hibernate.validator.test.cdi.internal.beanmetadataclassnormalizer; + +public interface CustomProxy { +} diff --git a/cdi/src/test/java/org/hibernate/validator/test/cdi/internal/beanmetadataclassnormalizer/CustomProxyBeanMetaDataClassNormalizer.java b/cdi/src/test/java/org/hibernate/validator/test/cdi/internal/beanmetadataclassnormalizer/CustomProxyBeanMetaDataClassNormalizer.java new file mode 100644 index 0000000000..2e59a3819e --- /dev/null +++ b/cdi/src/test/java/org/hibernate/validator/test/cdi/internal/beanmetadataclassnormalizer/CustomProxyBeanMetaDataClassNormalizer.java @@ -0,0 +1,89 @@ +/* + * Hibernate Validator, declare and validate application constraints + * + * License: Apache License, Version 2.0 + * See the license.txt file in the root directory or . + */ +package org.hibernate.validator.test.cdi.internal.beanmetadataclassnormalizer; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; +import java.util.Collections; +import java.util.Set; +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.context.spi.CreationalContext; +import javax.enterprise.inject.literal.NamedLiteral; +import javax.enterprise.inject.spi.Bean; +import javax.enterprise.inject.spi.InjectionPoint; + +import org.hibernate.validator.cdi.spi.BeanNames; +import org.hibernate.validator.metadata.BeanMetaDataClassNormalizer; + + +public class CustomProxyBeanMetaDataClassNormalizer + implements BeanMetaDataClassNormalizer, Bean { + + @Override + public Class normalize(Class clazz) { + if ( CustomProxy.class.isAssignableFrom( clazz ) ) { + return clazz.getSuperclass(); + } + return clazz; + } + + @Override + public Class getBeanClass() { + return BeanMetaDataClassNormalizer.class; + } + + @Override + public Set getInjectionPoints() { + return Collections.emptySet(); + } + + @Override + public boolean isNullable() { + return false; + } + + @Override + public BeanMetaDataClassNormalizer create(CreationalContext creationalContext) { + return new CustomProxyBeanMetaDataClassNormalizer(); + } + + @Override + public void destroy(BeanMetaDataClassNormalizer beanMetaDataClassNormalizer, + CreationalContext creationalContext) { + // Nothing to do + } + + @Override + public Set getTypes() { + return Collections.singleton( BeanMetaDataClassNormalizer.class ); + } + + @Override + public Set getQualifiers() { + return Collections.singleton( NamedLiteral.of( BeanNames.BEAN_META_DATA_CLASS_NORMALIZER ) ); + } + + @Override + public Class getScope() { + return ApplicationScoped.class; + } + + @Override + public String getName() { + return BeanNames.BEAN_META_DATA_CLASS_NORMALIZER; + } + + @Override + public Set> getStereotypes() { + return Collections.emptySet(); + } + + @Override + public boolean isAlternative() { + return false; + } +} diff --git a/cdi/src/test/java/org/hibernate/validator/test/cdi/internal/beanmetadataclassnormalizer/CustomProxyBeanMetadataClassNormalizerCdiExtension.java b/cdi/src/test/java/org/hibernate/validator/test/cdi/internal/beanmetadataclassnormalizer/CustomProxyBeanMetadataClassNormalizerCdiExtension.java new file mode 100644 index 0000000000..7ea42a77f8 --- /dev/null +++ b/cdi/src/test/java/org/hibernate/validator/test/cdi/internal/beanmetadataclassnormalizer/CustomProxyBeanMetadataClassNormalizerCdiExtension.java @@ -0,0 +1,18 @@ +/* + * Hibernate Validator, declare and validate application constraints + * + * License: Apache License, Version 2.0 + * See the license.txt file in the root directory or . + */ +package org.hibernate.validator.test.cdi.internal.beanmetadataclassnormalizer; + +import javax.enterprise.event.Observes; +import javax.enterprise.inject.spi.AfterBeanDiscovery; +import javax.enterprise.inject.spi.Extension; + +public class CustomProxyBeanMetadataClassNormalizerCdiExtension implements Extension { + + public void addEjbProxyNormalizer(@Observes AfterBeanDiscovery afterBeanDiscovery) { + afterBeanDiscovery.addBean( new CustomProxyBeanMetaDataClassNormalizer() ); + } +} diff --git a/cdi/src/test/java/org/hibernate/validator/test/cdi/internal/beanmetadataclassnormalizer/ExtensionProvidedBeanMetadataClassNormalizerTest.java b/cdi/src/test/java/org/hibernate/validator/test/cdi/internal/beanmetadataclassnormalizer/ExtensionProvidedBeanMetadataClassNormalizerTest.java new file mode 100644 index 0000000000..e7b7778506 --- /dev/null +++ b/cdi/src/test/java/org/hibernate/validator/test/cdi/internal/beanmetadataclassnormalizer/ExtensionProvidedBeanMetadataClassNormalizerTest.java @@ -0,0 +1,102 @@ +/* + * Hibernate Validator, declare and validate application constraints + * + * License: Apache License, Version 2.0 + * See the license.txt file in the root directory or . + */ +package org.hibernate.validator.test.cdi.internal.beanmetadataclassnormalizer; + +import static org.assertj.core.api.Assertions.assertThat; + +import javax.inject.Inject; +import javax.validation.Validator; +import javax.validation.ValidatorFactory; +import javax.validation.constraints.DecimalMax; +import javax.validation.constraints.NotNull; + +import org.hibernate.validator.cdi.HibernateValidator; + +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.testng.Arquillian; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.asset.EmptyAsset; +import org.jboss.shrinkwrap.api.asset.StringAsset; +import org.jboss.shrinkwrap.api.spec.JavaArchive; + +import org.testng.annotations.Test; + +public class ExtensionProvidedBeanMetadataClassNormalizerTest extends Arquillian { + + @Deployment + public static JavaArchive createDeployment() { + return ShrinkWrap.create( JavaArchive.class ) + .addAsManifestResource( EmptyAsset.INSTANCE, "beans.xml" ) + // Register the CDI extension that provides the normalizer bean + .addAsManifestResource( + new StringAsset( CustomProxyBeanMetadataClassNormalizerCdiExtension.class.getName() ), + "services/javax.enterprise.inject.spi.Extension" + ); + } + + @HibernateValidator + @Inject + ValidatorFactory validatorFactory; + + @HibernateValidator + @Inject + Validator validator; + + @Inject + ValidatorFactory defaultValidatorFactory; + + @Inject + Validator defaultValidator; + + @Test + public void testProxyMetadataIgnoredWithQualifiedValidator() throws Exception { + assertThat( validator ).isNotNull(); + doTest( validator ); + } + + @Test + public void testProxyMetadataIgnoredWithDefaultValidator() throws Exception { + assertThat( defaultValidator ).isNotNull(); + doTest( defaultValidator ); + } + + @Test + public void testProxyMetadataIgnoredWithQualifiedValidatorFactory() throws Exception { + assertThat( validatorFactory ).isNotNull(); + doTest( validatorFactory.getValidator() ); + } + + @Test + public void testProxyMetadataIgnoredWithDefaultValidatorFactory() throws Exception { + assertThat( defaultValidatorFactory ).isNotNull(); + doTest( defaultValidatorFactory.getValidator() ); + } + + private void doTest(Validator validator) { + assertThat( validator ).isNotNull(); + /* + * Even though we pass an instance of the proxy class that has invalid annotations, + * we expect those to be ignored + * because of the class normalizer we defined. + */ + assertThat( validator.validate( new TestEntityProxy() ) ).hasSize( 1 ); + } + + public static class TestEntity { + @NotNull + private String foo; + } + + public static class TestEntityProxy extends TestEntity implements CustomProxy { + /* + * This is invalid, but should be ignored because it's defined in a proxy class which gets ignored + * because of the class normalizer we defined. + */ + @DecimalMax(value = "foo") + private String foo; + } +}