From 58805ff9e3980653c86c709cbbffca5b27568852 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 21 May 2023 17:32:27 -0400 Subject: [PATCH 1/2] now write default values to adapters --- .../validation/generator/AnnotationUtil.java | 22 ++++++++++++++----- .../core/adapters/BasicAdapters.java | 7 +++--- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/validator-generator/src/main/java/io/avaje/validation/generator/AnnotationUtil.java b/validator-generator/src/main/java/io/avaje/validation/generator/AnnotationUtil.java index fd4a5b72..c713e0cc 100644 --- a/validator-generator/src/main/java/io/avaje/validation/generator/AnnotationUtil.java +++ b/validator-generator/src/main/java/io/avaje/validation/generator/AnnotationUtil.java @@ -3,10 +3,13 @@ import static java.util.stream.Collectors.joining; import java.util.List; +import java.util.Optional; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.AnnotationValue; +import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.VariableElement; +import javax.lang.model.util.ElementFilter; final class AnnotationUtil { private AnnotationUtil() {} @@ -20,12 +23,22 @@ public static String getAnnotationAttributMap(AnnotationMirror annotationMirror) patternOp.ifPresent(p -> pattern(sb, p)); return sb.toString(); } - for (final var entry : annotationMirror.getElementValues().entrySet()) { + + for (final ExecutableElement member : + ElementFilter.methodsIn( + annotationMirror.getAnnotationType().asElement().getEnclosedElements())) { + + final var value = + Optional.ofNullable(annotationMirror.getElementValues().get(member)) + .orElseGet(member::getDefaultValue); + if (value == null) { + continue; + } if (!first) { sb.append(", "); } - sb.append("\"" + entry.getKey().getSimpleName() + "\"").append(","); - writeVal(sb, entry.getValue()); + sb.append("\"" + member.getSimpleName() + "\"").append(","); + writeVal(sb, value); first = false; } sb.append(")"); @@ -65,8 +78,7 @@ private static void writeVal(final StringBuilder sb, final AnnotationValue annot } sb.append(")"); // Handle enum values - } else if (value instanceof VariableElement) { - final var element = (VariableElement) value; + } else if (value instanceof final VariableElement element) { sb.append(element.asType().toString() + "." + element.toString()); // handle annotation values } else if (value instanceof AnnotationMirror) { diff --git a/validator/src/main/java/io/avaje/validation/core/adapters/BasicAdapters.java b/validator/src/main/java/io/avaje/validation/core/adapters/BasicAdapters.java index 51e62950..a1b43e65 100644 --- a/validator/src/main/java/io/avaje/validation/core/adapters/BasicAdapters.java +++ b/validator/src/main/java/io/avaje/validation/core/adapters/BasicAdapters.java @@ -4,7 +4,6 @@ import java.util.Collection; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.function.Predicate; import java.util.regex.Pattern; @@ -44,7 +43,7 @@ public PatternAdapter(ValidationContext.Message message, Map att this.message = message; int flags = 0; - for (final var flag : Optional.ofNullable((List) attributes.get("flags")).orElseGet(List::of)) { + for (final var flag : (List) attributes.get("flags")) { flags |= flag.getValue(); } this.pattern = Pattern.compile((String) attributes.get("regexp"), flags).asMatchPredicate().negate(); @@ -68,8 +67,8 @@ private static final class SizeAdapter implements ValidationAdapter { public SizeAdapter(ValidationContext.Message message, Map attributes) { this.message = message; - this.min = Optional.ofNullable((Integer) attributes.get("min")).orElse(0); - this.max = Optional.ofNullable((Integer) attributes.get("max")).orElse(Integer.MAX_VALUE); + this.min = (int) attributes.get("min"); + this.max = (int) attributes.get("max"); } @Override From 82c97aad5df6045300e18e6303ff2a9a31f6d426 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Sun, 21 May 2023 18:43:59 -0400 Subject: [PATCH 2/2] fix tests --- .../test/java/example/avaje/ACustomer.java | 4 +- .../io/avaje/validation/constraints/Size.java | 11 ++- .../validation/adapter/ValidationContext.java | 13 ++- .../io/avaje/validation/core/DValidator.java | 36 +++++--- .../core/adapters/BasicAdapters.java | 31 +++---- .../io/avaje/validation/Messages.properties | 88 +++++++++---------- .../avaje/validation/Messages_de.properties | 86 +++++++++--------- .../validation/core/DTemplateLookupTest.java | 12 +-- 8 files changed, 153 insertions(+), 128 deletions(-) diff --git a/blackbox-test/src/test/java/example/avaje/ACustomer.java b/blackbox-test/src/test/java/example/avaje/ACustomer.java index 13311eab..93208978 100644 --- a/blackbox-test/src/test/java/example/avaje/ACustomer.java +++ b/blackbox-test/src/test/java/example/avaje/ACustomer.java @@ -1,8 +1,8 @@ package example.avaje; +import io.avaje.validation.constraints.NotBlank; +import io.avaje.validation.constraints.Size; import jakarta.validation.Valid; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Size; @Valid public class ACustomer { diff --git a/validator-constraints/src/main/java/io/avaje/validation/constraints/Size.java b/validator-constraints/src/main/java/io/avaje/validation/constraints/Size.java index 5de532e8..accf8c82 100644 --- a/validator-constraints/src/main/java/io/avaje/validation/constraints/Size.java +++ b/validator-constraints/src/main/java/io/avaje/validation/constraints/Size.java @@ -1,6 +1,11 @@ package io.avaje.validation.constraints; -import java.lang.annotation.*; +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; @Target({ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @@ -10,9 +15,9 @@ Class[] groups() default {}; - int min(); + int min() default 0; - int max(); + int max() default Integer.MAX_VALUE; @Target({ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) diff --git a/validator/src/main/java/io/avaje/validation/adapter/ValidationContext.java b/validator/src/main/java/io/avaje/validation/adapter/ValidationContext.java index e2caab47..267e53b9 100644 --- a/validator/src/main/java/io/avaje/validation/adapter/ValidationContext.java +++ b/validator/src/main/java/io/avaje/validation/adapter/ValidationContext.java @@ -28,10 +28,15 @@ public interface ValidationContext { */ String message(String key, Map attributes); - /** - * Return the message object held by a validation adapter - */ - Message message2(String key, Map attributes); + /** + * Return the message object held by a validation adapter + */ + Message message2(Map attributes); + + /** + * Return the message object held by a validation adapter + */ + Message message2(String defaultKey, Map attributes); interface Message { diff --git a/validator/src/main/java/io/avaje/validation/core/DValidator.java b/validator/src/main/java/io/avaje/validation/core/DValidator.java index 47712e2b..874a1ee3 100644 --- a/validator/src/main/java/io/avaje/validation/core/DValidator.java +++ b/validator/src/main/java/io/avaje/validation/core/DValidator.java @@ -7,7 +7,12 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Type; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.ServiceLoader; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import io.avaje.lang.Nullable; @@ -32,7 +37,7 @@ final class DValidator implements Validator, ValidationContext { MessageInterpolator interpolator, LocaleResolver localeResolver) { this.localeResolver = localeResolver; - var defaultResourceBundle = new DResourceBundleManager("io.avaje.validation.Messages", localeResolver); + final var defaultResourceBundle = new DResourceBundleManager("io.avaje.validation.Messages", localeResolver); this.templateLookup = new DTemplateLookup(defaultResourceBundle); this.interpolator = interpolator; @@ -74,13 +79,22 @@ public String message(String key, Map attributes) { return msg; } + @Override + public Message message2(Map attributes) { + final String keyOrTemplate = (String)attributes.get("message"); + + // if configured to support only 1 Locale then we can do the lookup and message translation once and early + // otherwise we defer as the final message is locale specific + return new DMessage(keyOrTemplate, attributes); + } + @Override public Message message2(String defaultKey, Map attributes) { String keyOrTemplate = (String)attributes.get("message"); if (keyOrTemplate == null) { - // lookup default message for the given key - keyOrTemplate = defaultKey; - } + // lookup default message for the given key + keyOrTemplate = defaultKey; + } // if configured to support only 1 Locale then we can do the lookup and message translation once and early // otherwise we defer as the final message is locale specific return new DMessage(keyOrTemplate, attributes); @@ -119,14 +133,14 @@ ValidationRequest request(@Nullable Locale locale) { String interpolate(Message msg, Locale requestLocale) { // resolve the locale to use to produce the message - Locale locale = localeResolver.resolve(requestLocale); + final Locale locale = localeResolver.resolve(requestLocale); // lookup in resource bundles using resolved locale and template - String template = templateLookup.lookup(msg.template(), locale); + final String template = templateLookup.lookup(msg.template(), locale); // translate the template using msg attributes - Map attributes = msg.attributes(); - Set> entries = attributes.entrySet(); + final Map attributes = msg.attributes(); + final Set> entries = attributes.entrySet(); String result = template; - for (Map.Entry entry : entries) { + for (final Map.Entry entry : entries) { // needs work here to improve functionality, support local specific value formatting eg Duration Max result = result.replace('{' + entry.getKey() + '}', String.valueOf(entry.getValue())); } @@ -188,7 +202,7 @@ public DValidator build() { registerComponents(); //todo: sort out LocaleResolver initialisation, just hard coded EN and DE for now ... - LocaleResolver localeResolver = new DLocaleResolver(Locale.ENGLISH, Locale.GERMAN); + final LocaleResolver localeResolver = new DLocaleResolver(Locale.ENGLISH, Locale.GERMAN); final var interpolator = ServiceLoader.load(MessageInterpolator.class) .findFirst() diff --git a/validator/src/main/java/io/avaje/validation/core/adapters/BasicAdapters.java b/validator/src/main/java/io/avaje/validation/core/adapters/BasicAdapters.java index a1b43e65..d0f09389 100644 --- a/validator/src/main/java/io/avaje/validation/core/adapters/BasicAdapters.java +++ b/validator/src/main/java/io/avaje/validation/core/adapters/BasicAdapters.java @@ -4,6 +4,7 @@ import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.function.Predicate; import java.util.regex.Pattern; @@ -17,21 +18,21 @@ private BasicAdapters() {} public static final ValidationContext.AnnotationFactory FACTORY = (annotationType, context, attributes) -> switch (annotationType.getSimpleName()) { - case "Email" -> new EmailAdapter(context.message("Email", attributes), attributes); - case "Null" -> new NullAdapter(context.message2("{avaje.Null.message}", attributes)); - case "NotNull", "NonNull" -> new NotNullAdapter(context.message2("{avaje.NotNull.message}", attributes)); - case "AssertTrue" -> new AssertBooleanAdapter(context.message2("{avaje.AssertTrue.message}", attributes), false); - case "AssertFalse" -> new AssertBooleanAdapter(context.message2("{avaje.AssertFalse.message}", attributes), true); - case "NotBlank" -> new NotBlankAdapter(context.message2("{avaje.NotBlank.message}", attributes)); - case "NotEmpty" -> new NotEmptyAdapter(context.message2("{avaje.NotEmpty.message}", attributes)); - case "Past" -> new FuturePastAdapter(context.message("Past", attributes), true, false); - case "PastOrPresent" -> new FuturePastAdapter(context.message("PastOrPresent", attributes), true, true); - case "Future" -> new FuturePastAdapter(context.message("Future", attributes), false, false); - case "FutureOrPresent" -> new FuturePastAdapter(context.message("FutureOrPresent", attributes), false, true); - case "Pattern" -> new PatternAdapter(context.message2("{avaje.Pattern.message}", attributes), attributes); - case "Size" -> new SizeAdapter(context.message2("{avaje.Size.message}", attributes), attributes); - default -> null; - }; + case "Email" -> new EmailAdapter(context.message("Email", attributes), attributes); + case "Null" -> new NullAdapter(context.message2("{avaje.validation.constraints.Null.message}", attributes)); + case "NotNull", "NonNull" -> new NotNullAdapter(context.message2("{avaje.validation.constraints.NotNull.message}", attributes)); + case "AssertTrue" -> new AssertBooleanAdapter(context.message2("{avaje.validation.constraints.AssertTrue.message}", attributes), false); + case "AssertFalse" -> new AssertBooleanAdapter(context.message2("{avaje.validation.constraints.AssertFalse.message}", attributes), true); + case "NotBlank" -> new NotBlankAdapter(context.message2("{avaje.validation.constraints.NotBlank.message}", attributes)); + case "NotEmpty" -> new NotEmptyAdapter(context.message2("{avaje.validation.constraints.NotEmpty.message}", attributes)); + case "Past" -> new FuturePastAdapter(context.message("Past", attributes), true, false); + case "PastOrPresent" -> new FuturePastAdapter(context.message("PastOrPresent", attributes), true, true); + case "Future" -> new FuturePastAdapter(context.message("Future", attributes), false, false); + case "FutureOrPresent" -> new FuturePastAdapter(context.message("FutureOrPresent", attributes), false, true); + case "Pattern" -> new PatternAdapter(context.message2("{avaje.validation.constraints.Pattern.message}", attributes), attributes); + case "Size" -> new SizeAdapter(context.message2("{avaje.validation.constraints.Size.message}", attributes), attributes); + default -> null; + }; private static final class PatternAdapter implements ValidationAdapter { diff --git a/validator/src/main/resources/io/avaje/validation/Messages.properties b/validator/src/main/resources/io/avaje/validation/Messages.properties index f4bd17b2..409cfbc1 100644 --- a/validator/src/main/resources/io/avaje/validation/Messages.properties +++ b/validator/src/main/resources/io/avaje/validation/Messages.properties @@ -1,46 +1,46 @@ -avaje.AssertFalse.message = must be false -avaje.AssertTrue.message = must be true -avaje.DecimalMax.message = must be less than ${inclusive == true ? 'or equal to ' : ''}{value} -avaje.DecimalMin.message = must be greater than ${inclusive == true ? 'or equal to ' : ''}{value} -avaje.Digits.message = numeric value out of bounds (<{integer} digits>.<{fraction} digits> expected) -avaje.Email.message = must be a well-formed email address -avaje.Future.message = must be a future date -avaje.FutureOrPresent.message = must be a date in the present or in the future -avaje.Max.message = must be less than or equal to {value} -avaje.Min.message = must be greater than or equal to {value} -avaje.Negative.message = must be less than 0 -avaje.NegativeOrZero.message = must be less than or equal to 0 -avaje.NotBlank.message = must not be blank -avaje.NotEmpty.message = must not be empty -avaje.NotNull.message = must not be null -avaje.Null.message = must be null -avaje.Past.message = must be a past date -avaje.PastOrPresent.message = must be a date in the past or in the present -avaje.Pattern.message = must match "{regexp}" -avaje.Positive.message = must be greater than 0 -avaje.PositiveOrZero.message = must be greater than or equal to 0 -avaje.Size.message = size must be between {min} and {max} +avaje.validation.constraints.AssertFalse.message = must be false +avaje.validation.constraints.AssertTrue.message = must be true +avaje.validation.constraints.DecimalMax.message = must be less than ${inclusive == true ? 'or equal to ' : ''}{value} +avaje.validation.constraints.DecimalMin.message = must be greater than ${inclusive == true ? 'or equal to ' : ''}{value} +avaje.validation.constraints.Digits.message = numeric value out of bounds (<{integer} digits>.<{fraction} digits> expected) +avaje.validation.constraints.Email.message = must be a well-formed email address +avaje.validation.constraints.Future.message = must be a future date +avaje.validation.constraints.FutureOrPresent.message = must be a date in the present or in the future +avaje.validation.constraints.Max.message = must be less than or equal to {value} +avaje.validation.constraints.Min.message = must be greater than or equal to {value} +avaje.validation.constraints.Negative.message = must be less than 0 +avaje.validation.constraints.NegativeOrZero.message = must be less than or equal to 0 +avaje.validation.constraints.NotBlank.message = must not be blank +avaje.validation.constraints.NotEmpty.message = must not be empty +avaje.validation.constraints.NotNull.message = must not be null +avaje.validation.constraints.Null.message = must be null +avaje.validation.constraints.Past.message = must be a past date +avaje.validation.constraints.PastOrPresent.message = must be a date in the past or in the present +avaje.validation.constraints.Pattern.message = must match "{regexp}" +avaje.validation.constraints.Positive.message = must be greater than 0 +avaje.validation.constraints.PositiveOrZero.message = must be greater than or equal to 0 +avaje.validation.constraints.Size.message = size must be between {min} and {max} -avaje.ext.CreditCardNumber.message = invalid credit card number -avaje.ext.Currency.message = invalid currency (must be one of {value}) -avaje.ext.EAN.message = invalid {type} barcode -avaje.ext.Email.message = not a well-formed email address -avaje.ext.ISBN.message = invalid ISBN -avaje.ext.Length.message = length must be between {min} and {max} -avaje.ext.CodePointLength.message = length must be between {min} and {max} -avaje.ext.LuhnCheck.message = the check digit for {validatedValue} is invalid, Luhn Modulo 10 checksum failed -avaje.ext.Mod10Check.message = the check digit for {validatedValue} is invalid, Modulo 10 checksum failed -avaje.ext.Mod11Check.message = the check digit for {validatedValue} is invalid, Modulo 11 checksum failed -avaje.ext.ModCheck.message = the check digit for {validatedValue} is invalid, {modType} checksum failed -avaje.ext.Normalized.message = must be normalized -avaje.ext.NotBlank.message = may not be empty -avaje.ext.NotEmpty.message = may not be empty -avaje.ext.ParametersScriptAssert.message = script expression "{script}" didn't evaluate to true -avaje.ext.Range.message = must be between {min} and {max} -avaje.ext.ScriptAssert.message = script expression "{script}" didn't evaluate to true -avaje.ext.UniqueElements.message = must only contain unique elements -avaje.ext.URL.message = must be a valid URL -avaje.ext.UUID.message = must be a valid UUID +avaje.validation.constraints.ext.CreditCardNumber.message = invalid credit card number +avaje.validation.constraints.ext.Currency.message = invalid currency (must be one of {value}) +avaje.validation.constraints.ext.EAN.message = invalid {type} barcode +avaje.validation.constraints.ext.Email.message = not a well-formed email address +avaje.validation.constraints.ext.ISBN.message = invalid ISBN +avaje.validation.constraints.ext.Length.message = length must be between {min} and {max} +avaje.validation.constraints.ext.CodePointLength.message = length must be between {min} and {max} +avaje.validation.constraints.ext.LuhnCheck.message = the check digit for {validatedValue} is invalid, Luhn Modulo 10 checksum failed +avaje.validation.constraints.ext.Mod10Check.message = the check digit for {validatedValue} is invalid, Modulo 10 checksum failed +avaje.validation.constraints.ext.Mod11Check.message = the check digit for {validatedValue} is invalid, Modulo 11 checksum failed +avaje.validation.constraints.ext.ModCheck.message = the check digit for {validatedValue} is invalid, {modType} checksum failed +avaje.validation.constraints.ext.Normalized.message = must be normalized +avaje.validation.constraints.ext.NotBlank.message = may not be empty +avaje.validation.constraints.ext.NotEmpty.message = may not be empty +avaje.validation.constraints.ext.ParametersScriptAssert.message = script expression "{script}" didn't evaluate to true +avaje.validation.constraints.ext.Range.message = must be between {min} and {max} +avaje.validation.constraints.ext.ScriptAssert.message = script expression "{script}" didn't evaluate to true +avaje.validation.constraints.ext.UniqueElements.message = must only contain unique elements +avaje.validation.constraints.ext.URL.message = must be a valid URL +avaje.validation.constraints.ext.UUID.message = must be a valid UUID -avaje.ext.time.DurationMax.message = must be shorter than${inclusive == true ? ' or equal to' : ''}${days == 0 ? '' : days == 1 ? ' 1 day' : ' ' += days += ' days'}${hours == 0 ? '' : hours == 1 ? ' 1 hour' : ' ' += hours += ' hours'}${minutes == 0 ? '' : minutes == 1 ? ' 1 minute' : ' ' += minutes += ' minutes'}${seconds == 0 ? '' : seconds == 1 ? ' 1 second' : ' ' += seconds += ' seconds'}${millis == 0 ? '' : millis == 1 ? ' 1 milli' : ' ' += millis += ' millis'}${nanos == 0 ? '' : nanos == 1 ? ' 1 nano' : ' ' += nanos += ' nanos'} -avaje.ext.time.DurationMin.message = must be longer than${inclusive == true ? ' or equal to' : ''}${days == 0 ? '' : days == 1 ? ' 1 day' : ' ' += days += ' days'}${hours == 0 ? '' : hours == 1 ? ' 1 hour' : ' ' += hours += ' hours'}${minutes == 0 ? '' : minutes == 1 ? ' 1 minute' : ' ' += minutes += ' minutes'}${seconds == 0 ? '' : seconds == 1 ? ' 1 second' : ' ' += seconds += ' seconds'}${millis == 0 ? '' : millis == 1 ? ' 1 milli' : ' ' += millis += ' millis'}${nanos == 0 ? '' : nanos == 1 ? ' 1 nano' : ' ' += nanos += ' nanos'} +avaje.validation.constraints.ext.time.DurationMax.message = must be shorter than${inclusive == true ? ' or equal to' : ''}${days == 0 ? '' : days == 1 ? ' 1 day' : ' ' += days += ' days'}${hours == 0 ? '' : hours == 1 ? ' 1 hour' : ' ' += hours += ' hours'}${minutes == 0 ? '' : minutes == 1 ? ' 1 minute' : ' ' += minutes += ' minutes'}${seconds == 0 ? '' : seconds == 1 ? ' 1 second' : ' ' += seconds += ' seconds'}${millis == 0 ? '' : millis == 1 ? ' 1 milli' : ' ' += millis += ' millis'}${nanos == 0 ? '' : nanos == 1 ? ' 1 nano' : ' ' += nanos += ' nanos'} +avaje.validation.constraints.ext.time.DurationMin.message = must be longer than${inclusive == true ? ' or equal to' : ''}${days == 0 ? '' : days == 1 ? ' 1 day' : ' ' += days += ' days'}${hours == 0 ? '' : hours == 1 ? ' 1 hour' : ' ' += hours += ' hours'}${minutes == 0 ? '' : minutes == 1 ? ' 1 minute' : ' ' += minutes += ' minutes'}${seconds == 0 ? '' : seconds == 1 ? ' 1 second' : ' ' += seconds += ' seconds'}${millis == 0 ? '' : millis == 1 ? ' 1 milli' : ' ' += millis += ' millis'}${nanos == 0 ? '' : nanos == 1 ? ' 1 nano' : ' ' += nanos += ' nanos'} diff --git a/validator/src/main/resources/io/avaje/validation/Messages_de.properties b/validator/src/main/resources/io/avaje/validation/Messages_de.properties index f1fede91..f1cfeb7d 100644 --- a/validator/src/main/resources/io/avaje/validation/Messages_de.properties +++ b/validator/src/main/resources/io/avaje/validation/Messages_de.properties @@ -1,45 +1,45 @@ -avaje.AssertFalse.message = muss falsch sein -avaje.AssertTrue.message = muss wahr sein -avaje.DecimalMax.message = muss kleiner ${inclusive == true ? 'oder gleich ' : ''}{value} sein -avaje.DecimalMin.message = muss gr\u00f6\u00dfer ${inclusive == true ? 'oder gleich ' : ''}{value} sein -avaje.Digits.message = numerischer Wert au\u00dferhalb des g\u00fcltigen Bereichs (<{integer} digits>.<{fraction} digits> erwartet) -avaje.Email.message = muss eine korrekt formatierte E-Mail-Adresse sein -avaje.Future.message = muss ein Datum in der Zukunft sein -avaje.FutureOrPresent.message = muss ein Datum in der Gegenwart oder in der Zukunft sein -avaje.Max.message = muss kleiner-gleich {value} sein -avaje.Min.message = muss gr\u00f6\u00dfer-gleich {value} sein -avaje.Negative.message = muss kleiner als 0 sein -avaje.NegativeOrZero.message = muss kleiner-gleich 0 sein -avaje.NotBlank.message = darf nicht leer sein -avaje.NotEmpty.message = darf nicht leer sein -avaje.NotNull.message = darf nicht null sein -avaje.Null.message = muss null sein -avaje.Past.message = muss ein Datum in der Vergangenheit sein -avaje.PastOrPresent.message = muss ein Datum in der Vergangenheit oder in der Gegenwart sein -avaje.Pattern.message = muss mit "{regexp}" \u00fcbereinstimmen -avaje.Positive.message = muss gr\u00f6\u00dfer als 0 sein -avaje.PositiveOrZero.message = muss gr\u00f6\u00dfer-gleich 0 sein -avaje.Size.message = Gr\u00f6\u00dfe muss zwischen {min} und {max} sein +avaje.validation.constraints.AssertFalse.message = muss falsch sein +avaje.validation.constraints.AssertTrue.message = muss wahr sein +avaje.validation.constraints.DecimalMax.message = muss kleiner ${inclusive == true ? 'oder gleich ' : ''}{value} sein +avaje.validation.constraints.DecimalMin.message = muss gr\u00f6\u00dfer ${inclusive == true ? 'oder gleich ' : ''}{value} sein +avaje.validation.constraints.Digits.message = numerischer Wert au\u00dferhalb des g\u00fcltigen Bereichs (<{integer} digits>.<{fraction} digits> erwartet) +avaje.validation.constraints.Email.message = muss eine korrekt formatierte E-Mail-Adresse sein +avaje.validation.constraints.Future.message = muss ein Datum in der Zukunft sein +avaje.validation.constraints.FutureOrPresent.message = muss ein Datum in der Gegenwart oder in der Zukunft sein +avaje.validation.constraints.Max.message = muss kleiner-gleich {value} sein +avaje.validation.constraints.Min.message = muss gr\u00f6\u00dfer-gleich {value} sein +avaje.validation.constraints.Negative.message = muss kleiner als 0 sein +avaje.validation.constraints.NegativeOrZero.message = muss kleiner-gleich 0 sein +avaje.validation.constraints.NotBlank.message = darf nicht leer sein +avaje.validation.constraints.NotEmpty.message = darf nicht leer sein +avaje.validation.constraints.NotNull.message = darf nicht null sein +avaje.validation.constraints.Null.message = muss null sein +avaje.validation.constraints.Past.message = muss ein Datum in der Vergangenheit sein +avaje.validation.constraints.PastOrPresent.message = muss ein Datum in der Vergangenheit oder in der Gegenwart sein +avaje.validation.constraints.Pattern.message = muss mit "{regexp}" \u00fcbereinstimmen +avaje.validation.constraints.Positive.message = muss gr\u00f6\u00dfer als 0 sein +avaje.validation.constraints.PositiveOrZero.message = muss gr\u00f6\u00dfer-gleich 0 sein +avaje.validation.constraints.Size.message = Gr\u00f6\u00dfe muss zwischen {min} und {max} sein -avaje.ext.CreditCardNumber.message = ung\u00fcltige Kreditkartennummer -avaje.ext.Currency.message = ung\u00fcltige W\u00e4hrung (muss eine der folgenden sein: {value}) -avaje.ext.EAN.message = ung\u00fcltiger {type}-Barcode -avaje.ext.Email.message = muss eine korrekt formatierte E-Mail-Adresse sein -avaje.ext.ISBN.message = ung\u00fcltige ISBN -avaje.ext.Length.message = L\u00e4nge muss zwischen {min} und {max} sein -avaje.ext.CodePointLength.message = L\u00e4nge muss zwischen {min} und {max} sein -avaje.ext.LuhnCheck.message = die Pr\u00fcfziffer f\u00fcr {validatedValue} ist ung\u00fcltig, Luhn Modulo 10-Kontrollsumme ist fehlgeschlagen -avaje.ext.Mod10Check.message = die Pr\u00fcfziffer f\u00fcr {validatedValue} ist ung\u00fcltig, Modulo 10-Kontrollsumme ist fehlgeschlagen -avaje.ext.Mod11Check.message = die Pr\u00fcfziffer f\u00fcr {validatedValue} ist ung\u00fcltig, Modulo 11-Kontrollsumme ist fehlgeschlagen -avaje.ext.ModCheck.message = die Pr\u00fcfziffer f\u00fcr {validatedValue} ist ung\u00fcltig, {modType}-Kontrollsumme ist fehlgeschlagen -avaje.ext.NotBlank.message = darf nicht leer sein -avaje.ext.NotEmpty.message = darf nicht leer sein -avaje.ext.ParametersScriptAssert.message = die Evaluierung des Scriptausdrucks "{script}" ergab nicht true -avaje.ext.Range.message = muss zwischen {min} und {max} sein -avaje.ext.ScriptAssert.message = die Evaluierung des Scriptausdrucks "{script}" ergab nicht true -avaje.ext.UniqueElements.message = darf nur eindeutige Elemente enthalten -avaje.ext.URL.message = muss eine g\u00fcltige URL sein -avaje.ext.UUID.message = muss eine g\u00fcltige UUID sein +avaje.validation.constraints.ext.CreditCardNumber.message = ung\u00fcltige Kreditkartennummer +avaje.validation.constraints.ext.Currency.message = ung\u00fcltige W\u00e4hrung (muss eine der folgenden sein: {value}) +avaje.validation.constraints.ext.EAN.message = ung\u00fcltiger {type}-Barcode +avaje.validation.constraints.ext.Email.message = muss eine korrekt formatierte E-Mail-Adresse sein +avaje.validation.constraints.ext.ISBN.message = ung\u00fcltige ISBN +avaje.validation.constraints.ext.Length.message = L\u00e4nge muss zwischen {min} und {max} sein +avaje.validation.constraints.ext.CodePointLength.message = L\u00e4nge muss zwischen {min} und {max} sein +avaje.validation.constraints.ext.LuhnCheck.message = die Pr\u00fcfziffer f\u00fcr {validatedValue} ist ung\u00fcltig, Luhn Modulo 10-Kontrollsumme ist fehlgeschlagen +avaje.validation.constraints.ext.Mod10Check.message = die Pr\u00fcfziffer f\u00fcr {validatedValue} ist ung\u00fcltig, Modulo 10-Kontrollsumme ist fehlgeschlagen +avaje.validation.constraints.ext.Mod11Check.message = die Pr\u00fcfziffer f\u00fcr {validatedValue} ist ung\u00fcltig, Modulo 11-Kontrollsumme ist fehlgeschlagen +avaje.validation.constraints.ext.ModCheck.message = die Pr\u00fcfziffer f\u00fcr {validatedValue} ist ung\u00fcltig, {modType}-Kontrollsumme ist fehlgeschlagen +avaje.validation.constraints.ext.NotBlank.message = darf nicht leer sein +avaje.validation.constraints.ext.NotEmpty.message = darf nicht leer sein +avaje.validation.constraints.ext.ParametersScriptAssert.message = die Evaluierung des Scriptausdrucks "{script}" ergab nicht true +avaje.validation.constraints.ext.Range.message = muss zwischen {min} und {max} sein +avaje.validation.constraints.ext.ScriptAssert.message = die Evaluierung des Scriptausdrucks "{script}" ergab nicht true +avaje.validation.constraints.ext.UniqueElements.message = darf nur eindeutige Elemente enthalten +avaje.validation.constraints.ext.URL.message = muss eine g\u00fcltige URL sein +avaje.validation.constraints.ext.UUID.message = muss eine g\u00fcltige UUID sein -avaje.ext.time.DurationMax.message = muss k\u00fcrzer sein als${inclusive == true ? ' oder gleich' : ''}${days == 0 ? '' : days == 1 ? ' 1 Tag' : ' ' += days += ' Tage'}${hours == 0 ? '' : hours == 1 ? ' 1 Stunde' : ' ' += hours += ' Stunden'}${minutes == 0 ? '' : minutes == 1 ? ' 1 Minute' : ' ' += minutes += ' Minuten'}${seconds == 0 ? '' : seconds == 1 ? ' 1 Sekunde' : ' ' += seconds += ' Sekunden'}${millis == 0 ? '' : millis == 1 ? ' 1 Millisekunde' : ' ' += millis += ' Millisekunden'}${nanos == 0 ? '' : nanos == 1 ? ' 1 Nanosekunde' : ' ' += nanos += ' Nanosekunden'} -avaje.ext.time.DurationMin.message = muss gr\u00f6\u00dfer sein als${inclusive == true ? ' oder gleich' : ''}${days == 0 ? '' : days == 1 ? ' 1 Tag' : ' ' += days += ' Tage'}${hours == 0 ? '' : hours == 1 ? ' 1 Stunde' : ' ' += hours += ' Stunden'}${minutes == 0 ? '' : minutes == 1 ? ' 1 Minute' : ' ' += minutes += ' Minuten'}${seconds == 0 ? '' : seconds == 1 ? ' 1 Sekunde' : ' ' += seconds += ' Sekunden'}${millis == 0 ? '' : millis == 1 ? ' 1 Millisekunde' : ' ' += millis += ' Millisekunden'}${nanos == 0 ? '' : nanos == 1 ? ' 1 Nanosekunde' : ' ' += nanos += ' Nanosekunden'} +avaje.validation.constraints.ext.time.DurationMax.message = muss k\u00fcrzer sein als${inclusive == true ? ' oder gleich' : ''}${days == 0 ? '' : days == 1 ? ' 1 Tag' : ' ' += days += ' Tage'}${hours == 0 ? '' : hours == 1 ? ' 1 Stunde' : ' ' += hours += ' Stunden'}${minutes == 0 ? '' : minutes == 1 ? ' 1 Minute' : ' ' += minutes += ' Minuten'}${seconds == 0 ? '' : seconds == 1 ? ' 1 Sekunde' : ' ' += seconds += ' Sekunden'}${millis == 0 ? '' : millis == 1 ? ' 1 Millisekunde' : ' ' += millis += ' Millisekunden'}${nanos == 0 ? '' : nanos == 1 ? ' 1 Nanosekunde' : ' ' += nanos += ' Nanosekunden'} +avaje.validation.constraints.ext.time.DurationMin.message = muss gr\u00f6\u00dfer sein als${inclusive == true ? ' oder gleich' : ''}${days == 0 ? '' : days == 1 ? ' 1 Tag' : ' ' += days += ' Tage'}${hours == 0 ? '' : hours == 1 ? ' 1 Stunde' : ' ' += hours += ' Stunden'}${minutes == 0 ? '' : minutes == 1 ? ' 1 Minute' : ' ' += minutes += ' Minuten'}${seconds == 0 ? '' : seconds == 1 ? ' 1 Sekunde' : ' ' += seconds += ' Sekunden'}${millis == 0 ? '' : millis == 1 ? ' 1 Millisekunde' : ' ' += millis += ' Millisekunden'}${nanos == 0 ? '' : nanos == 1 ? ' 1 Nanosekunde' : ' ' += nanos += ' Nanosekunden'} diff --git a/validator/src/test/java/io/avaje/validation/core/DTemplateLookupTest.java b/validator/src/test/java/io/avaje/validation/core/DTemplateLookupTest.java index a42f9201..2890f6f5 100644 --- a/validator/src/test/java/io/avaje/validation/core/DTemplateLookupTest.java +++ b/validator/src/test/java/io/avaje/validation/core/DTemplateLookupTest.java @@ -1,31 +1,31 @@ package io.avaje.validation.core; -import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThat; import java.util.Locale; -import static org.assertj.core.api.Assertions.assertThat; +import org.junit.jupiter.api.Test; class DTemplateLookupTest { private final DTemplateLookup lookup; DTemplateLookupTest() { - var localeResolver = new DLocaleResolver(Locale.ENGLISH, Locale.GERMAN); - var defaultResourceBundle = new DResourceBundleManager("io.avaje.validation.Messages", localeResolver); + final var localeResolver = new DLocaleResolver(Locale.ENGLISH, Locale.GERMAN); + final var defaultResourceBundle = new DResourceBundleManager("io.avaje.validation.Messages", localeResolver); this.lookup = new DTemplateLookup(defaultResourceBundle); } @Test void lookupKnownKey() { - String key = "{avaje.AssertTrue.message}"; + final String key = "{avaje.validation.constraints.AssertTrue.message}"; assertThat(lookup.lookup(key, Locale.ENGLISH)).isEqualTo("must be true"); assertThat(lookup.lookup(key, Locale.GERMAN)).isEqualTo("muss wahr sein"); } @Test void lookupUnknownKey() { - String key = "My literal msg"; + final String key = "My literal msg"; assertThat(lookup.lookup(key, Locale.ENGLISH)).isEqualTo("My literal msg"); assertThat(lookup.lookup(key, Locale.GERMAN)).isEqualTo("My literal msg"); }