Skip to content

Commit

Permalink
GH-421 Add missing api. Remove useless method. (#421)
Browse files Browse the repository at this point in the history
  • Loading branch information
Rollczi authored Aug 27, 2024
1 parent 084e080 commit f2afe58
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,23 @@ class JakartaRawResultHandler<SENDER> implements ResultHandler<SENDER, JakartaRa

@Override
public void handle(Invocation<SENDER> invocation, JakartaRawResult result, ResultHandlerChain<SENDER> chain) {
List<String> list = result.getViolations().stream()
List<Object> list = result.getViolations().stream()
.map(entry -> getViolation(entry, settings.localeProvider.apply(invocation)))
.map(violation -> settings.toMessage(invocation, violation))
.collect(Collectors.toList());

Object message = settings.constraintViolationsMessage.get(invocation, new JakartaParsedResult(list));

chain.resolve(invocation, message);
chain.resolve(invocation, list);
}

private JakartaViolation<?> getViolation(JakartaRawResult.Entry entry, Locale locale) {
ConstraintViolation<Object> constraintViolation = entry.getViolation();
private JakartaViolation<?, ?> getViolation(JakartaRawResult.Entry entry, Locale locale) {
ConstraintViolation<Object> violation = entry.getViolation();

return new JakartaViolation<>(
constraintViolation.getConstraintDescriptor().getAnnotation().annotationType(),
constraintViolation,
violation.getConstraintDescriptor().getAnnotation().annotationType(),
violation.getInvalidValue(),
violation,
entry.getRequirement(),
getInterpolatedMessage(constraintViolation, locale),
getInterpolatedMessage(violation, locale),
entry.getRequirement().getName(),
schematicFormat, locale
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import dev.rollczi.litecommands.invocation.Invocation;
import dev.rollczi.litecommands.message.InvokedMessage;
import dev.rollczi.litecommands.shared.BiHashMap;
import dev.rollczi.litecommands.shared.BiMap;
import jakarta.validation.Validation;
import jakarta.validation.ValidatorFactory;

Expand All @@ -16,13 +18,10 @@ public class JakartaSettings<SENDER> {
Function<Invocation<SENDER>, Locale> localeProvider = ignored -> Locale.getDefault();
ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();

InvokedMessage<SENDER, Object, JakartaParsedResult> constraintViolationsMessage =
(invocation, parsedResult) -> String.format("Constraint violations: %n%s", parsedResult.asJoinedString());

private InvokedMessage<SENDER, String, JakartaViolation<?>> defaultViolationMessage =
private InvokedMessage<SENDER, ?, JakartaViolation<?, ?>> defaultViolationMessage =
(invocation, violation) -> String.format("%s - %s", violation.getFormattedParameterName(), violation.getMessage());

private Map<Class<? extends Annotation>, InvokedMessage<SENDER, String, ? extends JakartaViolation<?>>> violationMessages = new HashMap<>();
private BiMap<Class<? extends Annotation>, Class<?>, InvokedMessage<SENDER, ?, ? extends JakartaViolation<?, ?>>> violationMessages = new BiHashMap<>();

public JakartaSettings<SENDER> locale(Function<Invocation<SENDER>, Locale> localeProvider) {
this.localeProvider = localeProvider;
Expand All @@ -34,27 +33,42 @@ public JakartaSettings<SENDER> validatorFactory(ValidatorFactory validatorFactor
return this;
}

/**
* It is not recommended to use this method. Use {@link #violationMessage(Class, InvokedMessage)} instead.
* If you want to join all violations into one message, then implement your ResultHandler for JakartaRawResult type.
*/
@Deprecated
public JakartaSettings<SENDER> constraintViolationsMessage(InvokedMessage<SENDER, Object, JakartaParsedResult> message) {
this.constraintViolationsMessage = message;
return this;
throw new UnsupportedOperationException("Use violationMessage(Class, InvokedMessage) instead. If you want to join all violations into one message, then implement your handler: ResultHandler<SENDER, JakartaRawResult>.");
}

public <A extends Annotation> JakartaSettings<SENDER> violationMessage(Class<A> annotationType, InvokedMessage<SENDER, ?, JakartaViolation<A, Object>> message) {
return violationMessage(annotationType, Object.class, message);
}

public <A extends Annotation> JakartaSettings<SENDER> violationMessage(Class<A> annotationType, InvokedMessage<SENDER, String, JakartaViolation<A>> message) {
this.violationMessages.put(annotationType, message);
public <A extends Annotation, T> JakartaSettings<SENDER> violationMessage(Class<A> annotationType, Class<T> type, InvokedMessage<SENDER, ?, JakartaViolation<A, T>> message) {
this.violationMessages.put(annotationType, type, message);
return this;
}

public JakartaSettings<SENDER> violationMessage(InvokedMessage<SENDER, String, JakartaViolation<?>> message) {
public JakartaSettings<SENDER> violationMessage(InvokedMessage<SENDER, ?, JakartaViolation<?, ?>> message) {
this.defaultViolationMessage = message;
return this;
}

<A extends Annotation> String toMessage(Invocation<SENDER> invocation, JakartaViolation<A> violation) {
InvokedMessage<SENDER, String, JakartaViolation<A>> message = (InvokedMessage<SENDER, String, JakartaViolation<A>>) violationMessages.get(violation.getAnnotationType());
@SuppressWarnings("unchecked")
<A extends Annotation, T> Object toMessage(Invocation<SENDER> invocation, JakartaViolation<A, T> violation) {
InvokedMessage<SENDER, ?, JakartaViolation<A, T>> message = (InvokedMessage<SENDER, ?, JakartaViolation<A, T>>) violationMessages.get(violation.getAnnotationType(), violation.getInvalidValue().getClass());

if (message == null) {
message = (InvokedMessage<SENDER, ?, JakartaViolation<A, T>>) violationMessages.get(violation.getAnnotationType(), Object.class);
}

if (message == null) {
return defaultViolationMessage.get(invocation, violation);
}

return message != null
? message.get(invocation, violation)
: defaultViolationMessage.get(invocation, violation);
return message.get(invocation, violation);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,20 @@
import java.lang.annotation.Annotation;
import java.util.Locale;

public class JakartaViolation<A extends Annotation> {
public class JakartaViolation<A extends Annotation, T> {

private final Class<A> annotationType;
private final T value;
private final ConstraintViolation<Object> violation;
private final Requirement<?> requirement;
private final String message;
private final String parameterName;
private final SchematicFormat schematicFormat;
private final Locale locale;

public JakartaViolation(Class<A> annotationType, ConstraintViolation<Object> violation, Requirement<?> requirement, String message, String parameterName, SchematicFormat schematicFormat, Locale locale) {
public JakartaViolation(Class<A> annotationType, T value, ConstraintViolation<Object> violation, Requirement<?> requirement, String message, String parameterName, SchematicFormat schematicFormat, Locale locale) {
this.annotationType = annotationType;
this.value = value;
this.violation = violation;
this.requirement = requirement;
this.message = message;
Expand All @@ -27,6 +29,10 @@ public JakartaViolation(Class<A> annotationType, ConstraintViolation<Object> vio
this.locale = locale;
}

public T getInvalidValue() {
return value;
}

public Class<A> getAnnotationType() {
return annotationType;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,6 @@ public void negative(@Negative @Arg("number") int number) {}
: Locale.ENGLISH;
})

// constraint violations message
.constraintViolationsMessage((invocation, parsedResult) -> "Constraint violations: " + parsedResult.asJoinedString())

// global violation message
.violationMessage((invocation, violation) -> "Invalid value for " + violation.getFormattedParameterName())

Expand All @@ -76,38 +73,40 @@ public void negative(@Negative @Arg("number") int number) {}
: format("[Other] Range must be between %d and %d", range.min(), range.max());
})

// violation message for @Max annotation
.violationMessage(Max.class, Integer.class, (invocation, violation) -> "Invalid value: " + violation.getInvalidValue() + " for " + violation.getParameterName())
)
);

@Test
@DisplayName("should return configured message specific for @Size annotation")
void size() {
platform.execute("test size 1234")
.assertMessage("Constraint violations: Size must be between 5 and 10 for text");
.assertMessage("Size must be between 5 and 10 for text");
}

@Test
@DisplayName("should return configured message specific for @Range annotation and locale")
void range() {
platform.execute(TestPlatformSender.locale(Locale.ENGLISH), "test range 4")
.assertMessage("Constraint violations: [English] Range must be between 5 and 10");
.assertMessage("[English] Range must be between 5 and 10");

platform.execute(TestPlatformSender.locale(Locale.GERMAN), "test range 4")
.assertMessage("Constraint violations: [Other] Range must be between 5 and 10");
.assertMessage("[Other] Range must be between 5 and 10");
}

@Test
@DisplayName("should return configured message specific for @Max annotation")
void max() {
platform.execute("test max 2")
.assertMessage("Constraint violations: Invalid value for <number>");
.assertMessage("Invalid value: 2 for number");
}

@Test
@DisplayName("should return configured message specific for @Min annotation")
@DisplayName("should return configured message")
void min() {
platform.execute("test min 0")
.assertMessage("Constraint violations: Invalid value for <number>");
.assertMessage("Invalid value for <number>");
}

}

0 comments on commit f2afe58

Please sign in to comment.