From 18a7887737e28811a9904a441e775a4a303782c2 Mon Sep 17 00:00:00 2001 From: Michael Schnell Date: Sat, 2 Mar 2024 12:36:14 +0100 Subject: [PATCH] Added new exception for constraint violations --- .../core/ConstraintViolationException.java | 40 +++++++++++++++ .../ConstraintViolationExceptionTest.java | 51 +++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 core/src/main/java/org/fuin/objects4j/core/ConstraintViolationException.java create mode 100644 core/src/test/java/org/fuin/objects4j/core/ConstraintViolationExceptionTest.java diff --git a/core/src/main/java/org/fuin/objects4j/core/ConstraintViolationException.java b/core/src/main/java/org/fuin/objects4j/core/ConstraintViolationException.java new file mode 100644 index 0000000..8fa4804 --- /dev/null +++ b/core/src/main/java/org/fuin/objects4j/core/ConstraintViolationException.java @@ -0,0 +1,40 @@ +package org.fuin.objects4j.core; + +import jakarta.validation.ConstraintViolation; +import jakarta.validation.constraints.NotEmpty; +import org.fuin.objects4j.common.Contract; + +import java.util.Collections; +import java.util.Objects; +import java.util.Set; + +/** + * On or more constraint violations are considered an error. + */ +public final class ConstraintViolationException extends Exception { + + private final Set> violations; + + /** + * Constructor with mandatory data. + * + * @param violations Violations that caused the error. + */ + public ConstraintViolationException(@NotEmpty final Set> violations) { + super(Contract.asString(violations, ", ")); + this.violations = Objects.requireNonNull(violations, "violations==null)"); + if (violations.isEmpty()) { + throw new IllegalArgumentException("List of violations is empty"); + } + } + + /** + * Returns the violations that caused the error. + * + * @return Immutable set of violations. + */ + @NotEmpty + public Set> getViolations() { + return Collections.unmodifiableSet(violations); + } +} diff --git a/core/src/test/java/org/fuin/objects4j/core/ConstraintViolationExceptionTest.java b/core/src/test/java/org/fuin/objects4j/core/ConstraintViolationExceptionTest.java new file mode 100644 index 0000000..1a2f870 --- /dev/null +++ b/core/src/test/java/org/fuin/objects4j/core/ConstraintViolationExceptionTest.java @@ -0,0 +1,51 @@ +package org.fuin.objects4j.core; + +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.Validator; +import jakarta.validation.ValidatorFactory; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import org.junit.jupiter.api.Test; + +import java.util.Set; + +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; + +/** + * Test for the {@link ConstraintViolationException} class. + */ +class ConstraintViolationExceptionTest { + + @Test + void testCreate() { + + // GIVEN + try (final ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory()) { + final Validator validator = validatorFactory.getValidator(); + final Set> violations = validator.validate(new Example()); + + // WHEN + final ConstraintViolationException testee = new ConstraintViolationException(violations); + + // THEN + assertThat(testee.getViolations()).containsOnly(violations.toArray(new ConstraintViolation[0])); + assertThat(testee.getMessage()).contains("Example.name"); + assertThat(testee.getMessage()).contains("Example.id"); + + } + + } + + private static final class Example { + + @NotNull + private Integer id; + + @NotEmpty + private String name; + + } + + +}