diff --git a/build.gradle b/build.gradle index fabc31a..3c1f06f 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { group = 'dev.root101.clean' -version = '4.2.1.RELEASE.20220531' +version = '4.2.2.RELEASE.20220613' repositories { jcenter() diff --git a/src/main/java/dev/root101/clean/core/app/services/ExceptionHandler.java b/src/main/java/dev/root101/clean/core/app/services/ExceptionHandler.java index a5c44db..d7e3b8e 100644 --- a/src/main/java/dev/root101/clean/core/app/services/ExceptionHandler.java +++ b/src/main/java/dev/root101/clean/core/app/services/ExceptionHandler.java @@ -22,8 +22,7 @@ /** * La idea es almacenar todas las excepciones o similar como un stack trace en - * la bd para acceder remoto. De igual manera ese módulo recivir posibles - * errores del cliente + * la bd para acceder remoto. * * @author Root101 (jhernandezb96@gmail.com, +53-5-426-8660) * @author JesusHdezWaterloo@Github @@ -39,7 +38,7 @@ public static ExceptionHandlerService registerExceptionService(ExceptionHandlerS Objects.requireNonNull(newService, "ExceptionHandlerService can't be null"); exceptionServices.add(newService); - + return newService; } diff --git a/src/main/java/dev/root101/clean/core/app/services/ExceptionHandlerServiceFunctional.java b/src/main/java/dev/root101/clean/core/app/services/ExceptionHandlerServiceFunctional.java index 4f2782f..c01057c 100644 --- a/src/main/java/dev/root101/clean/core/app/services/ExceptionHandlerServiceFunctional.java +++ b/src/main/java/dev/root101/clean/core/app/services/ExceptionHandlerServiceFunctional.java @@ -47,7 +47,7 @@ public final void addHandler(Consumer consumer, Class... types) { @Override public void handleException(Throwable ex) { Class type = ex.getClass(); - + exceptionsMap.forEach((t, u) -> { if (t.isAssignableFrom(type)) { u.accept(ex); diff --git a/src/main/java/dev/root101/clean/core/exceptions/BadRequestException.java b/src/main/java/dev/root101/clean/core/exceptions/BadRequestException.java index 3cc9b42..da300e7 100644 --- a/src/main/java/dev/root101/clean/core/exceptions/BadRequestException.java +++ b/src/main/java/dev/root101/clean/core/exceptions/BadRequestException.java @@ -16,7 +16,9 @@ */ package dev.root101.clean.core.exceptions; -import org.springframework.http.HttpStatus;; +import org.springframework.http.HttpStatus; + +; /** * diff --git a/src/main/java/dev/root101/clean/core/exceptions/ConflictException.java b/src/main/java/dev/root101/clean/core/exceptions/ConflictException.java index 46c3a0c..bafa6b7 100644 --- a/src/main/java/dev/root101/clean/core/exceptions/ConflictException.java +++ b/src/main/java/dev/root101/clean/core/exceptions/ConflictException.java @@ -16,7 +16,9 @@ */ package dev.root101.clean.core.exceptions; -import org.springframework.http.HttpStatus;; +import org.springframework.http.HttpStatus; + +; /** * diff --git a/src/main/java/dev/root101/clean/core/exceptions/ForbiddenException.java b/src/main/java/dev/root101/clean/core/exceptions/ForbiddenException.java index 59d1e24..b8984fe 100644 --- a/src/main/java/dev/root101/clean/core/exceptions/ForbiddenException.java +++ b/src/main/java/dev/root101/clean/core/exceptions/ForbiddenException.java @@ -16,7 +16,9 @@ */ package dev.root101.clean.core.exceptions; -import org.springframework.http.HttpStatus;; +import org.springframework.http.HttpStatus; + +; /** * diff --git a/src/main/java/dev/root101/clean/core/exceptions/InternalServerErrorException.java b/src/main/java/dev/root101/clean/core/exceptions/InternalServerErrorException.java index 038a251..6737519 100644 --- a/src/main/java/dev/root101/clean/core/exceptions/InternalServerErrorException.java +++ b/src/main/java/dev/root101/clean/core/exceptions/InternalServerErrorException.java @@ -16,7 +16,9 @@ */ package dev.root101.clean.core.exceptions; -import org.springframework.http.HttpStatus;; +import org.springframework.http.HttpStatus; + +; /** * diff --git a/src/main/java/dev/root101/clean/core/exceptions/NotFoundException.java b/src/main/java/dev/root101/clean/core/exceptions/NotFoundException.java index cd1538f..d8ac647 100644 --- a/src/main/java/dev/root101/clean/core/exceptions/NotFoundException.java +++ b/src/main/java/dev/root101/clean/core/exceptions/NotFoundException.java @@ -16,7 +16,9 @@ */ package dev.root101.clean.core.exceptions; -import org.springframework.http.HttpStatus;; +import org.springframework.http.HttpStatus; + +; /** * diff --git a/src/main/java/dev/root101/clean/core/exceptions/PaymentRequiredException.java b/src/main/java/dev/root101/clean/core/exceptions/PaymentRequiredException.java index 41d401e..cee48a5 100644 --- a/src/main/java/dev/root101/clean/core/exceptions/PaymentRequiredException.java +++ b/src/main/java/dev/root101/clean/core/exceptions/PaymentRequiredException.java @@ -16,7 +16,9 @@ */ package dev.root101.clean.core.exceptions; -import org.springframework.http.HttpStatus;; +import org.springframework.http.HttpStatus; + +; /** * diff --git a/src/main/java/dev/root101/clean/core/exceptions/UnauthorizedException.java b/src/main/java/dev/root101/clean/core/exceptions/UnauthorizedException.java index 91e7cb5..ef50091 100644 --- a/src/main/java/dev/root101/clean/core/exceptions/UnauthorizedException.java +++ b/src/main/java/dev/root101/clean/core/exceptions/UnauthorizedException.java @@ -16,7 +16,9 @@ */ package dev.root101.clean.core.exceptions; -import org.springframework.http.HttpStatus;; +import org.springframework.http.HttpStatus; + +; /** * diff --git a/src/main/java/dev/root101/clean/core/exceptions/UnprocessableEntityException.java b/src/main/java/dev/root101/clean/core/exceptions/UnprocessableEntityException.java index fac8a37..e33dd32 100644 --- a/src/main/java/dev/root101/clean/core/exceptions/UnprocessableEntityException.java +++ b/src/main/java/dev/root101/clean/core/exceptions/UnprocessableEntityException.java @@ -16,7 +16,9 @@ */ package dev.root101.clean.core.exceptions; -import org.springframework.http.HttpStatus;; +import org.springframework.http.HttpStatus; + +; /** * diff --git a/src/main/java/dev/root101/clean/core/exceptions/ValidationException.java b/src/main/java/dev/root101/clean/core/exceptions/ValidationException.java index b2074ee..390b916 100644 --- a/src/main/java/dev/root101/clean/core/exceptions/ValidationException.java +++ b/src/main/java/dev/root101/clean/core/exceptions/ValidationException.java @@ -1,5 +1,6 @@ package dev.root101.clean.core.exceptions; +import java.util.Arrays; import java.util.List; import org.springframework.http.HttpStatus; @@ -30,4 +31,9 @@ public record ValidationErrorMessage( String mensaje) { } + + @Override + public String toString() { + return "ValidationException{" + "statusCode=" + statusCode + ", messages=" + Arrays.toString(messages.toArray()) + '}'; + } } diff --git a/src/main/java/dev/root101/clean/core/utils/validation/ValidationService.java b/src/main/java/dev/root101/clean/core/utils/validation/ValidationService.java index 677b831..8eda814 100644 --- a/src/main/java/dev/root101/clean/core/utils/validation/ValidationService.java +++ b/src/main/java/dev/root101/clean/core/utils/validation/ValidationService.java @@ -1,36 +1,111 @@ package dev.root101.clean.core.utils.validation; import dev.root101.clean.core.exceptions.ValidationException; +import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.stream.Collectors; +import javax.validation.Configuration; import javax.validation.ConstraintViolation; +import javax.validation.MessageInterpolator; +import javax.validation.Validation; import javax.validation.Validator; +import org.springframework.util.ClassUtils; public class ValidationService { + //store the config + private static final Configuration CONFIG = Validation.byDefaultProvider().configure(); + //Created static to avoid recreated every time a validation occur - private static final Validator DEFAULT_VALIDATOR = javax.validation.Validation.buildDefaultValidatorFactory().getValidator(); + private static Validator DEFAULT_VALIDATOR = CONFIG.buildValidatorFactory().getValidator(); - public static Set> validate(Object object) { - return DEFAULT_VALIDATOR.validate(object); + public static MessageInterpolator defaultMessageInterpolator() { + return CONFIG.getDefaultMessageInterpolator(); } - public static void validateAndThrow(Object... objects) throws ValidationException { + public static void setMessageInterpolator(MessageInterpolator msgInterp) { + DEFAULT_VALIDATOR = CONFIG.messageInterpolator( + msgInterp + ).buildValidatorFactory().getValidator(); + } + + public static List> validate(Object... objects) { List> errors = new ArrayList<>(); - List.of(objects).forEach((object) -> { + + for (Object object : objects) { Set> aaa = DEFAULT_VALIDATOR.validate(object); errors.addAll(aaa); - }); + } + + return errors; + } + + public static List> validateRecursive(Object... objects) { + return validateRecursive(new ArrayList<>(), objects); + } + + public static void validateAndThrow(Object... objects) throws ValidationException { + List> errors = validate(objects); + if (!errors.isEmpty()) { + throw new ValidationException(convertMessages(errors)); + } + } + + public static void validateRecursiveAndThrow(Object... objects) throws ValidationException { + List> errors = validateRecursive(objects); if (!errors.isEmpty()) { throw new ValidationException(convertMessages(errors)); } } - private static List convertMessages(List> violation) { + public static List convertMessages(List> violation) { return violation.stream().map((viol) -> { - return new ValidationException.ValidationErrorMessage(viol.getPropertyPath().toString(), viol.getInvalidValue().toString(), viol.getMessage()); + return new ValidationException.ValidationErrorMessage(viol.getPropertyPath().toString(), viol.getInvalidValue() == null ? "null" : viol.getInvalidValue().toString(), viol.getMessage()); }).collect(Collectors.toList()); } + + private static List> validateRecursive(List> currentViolations, Object... objects) { + //recorro la lista de objetos a validar + for (Object object : objects) { + //si NO es null lo proceso. Null no tiene sentido validarlo(DEFAULT_VALIDATOR.validate(null) lanza excepcion), se deberia haber validado una capa arriba. + if (object != null) { + //si no es null compruebo si: + if (object instanceof Object[] arr) { + //es una instancia de arreglo, llamo a la recursividad con el arreglo + validateRecursive(currentViolations, arr); + } else if (object instanceof List list) { + //es una instancia de lista, la convierto en arreglo y llamo a la recursividad con el arreglo + validateRecursive(currentViolations, list.toArray()); + } else { + //no es ni una lista ni un arreglo, valido el objeto como objeto + currentViolations.addAll(DEFAULT_VALIDATOR.validate(object)); + + //luego recorro todos sus campos a ver si alguno no es primitivo + Field fields[] = object.getClass().getDeclaredFields(); + Object[] arr + = List.of(fields).stream() + //convierto los field en el objeto como tal + .map((field) -> { + field.setAccessible(true); + try { + return field.get(object); + } catch (IllegalAccessException | IllegalArgumentException e) { + System.out.println("Nunca debe entrar aqui"); + } + return null; + }) + //filtro de todos los valores los que NO sean primitivos + .filter((t) -> { + return t != null && !(ClassUtils.isPrimitiveOrWrapper(t.getClass()) || t instanceof String); + }) + .toArray(); + //de todos los campos que no son promitivos los valido + validateRecursive(currentViolations, arr); + } + } + } + return currentViolations; + } } diff --git a/src/main/java/dev/root101/clean/core/utils/validation/annotations/registers/DigitRegister.java b/src/main/java/dev/root101/clean/core/utils/validation/annotations/registers/DigitRegister.java index a1b121e..37bff5d 100644 --- a/src/main/java/dev/root101/clean/core/utils/validation/annotations/registers/DigitRegister.java +++ b/src/main/java/dev/root101/clean/core/utils/validation/annotations/registers/DigitRegister.java @@ -20,6 +20,7 @@ import dev.root101.clean.core.utils.validation.checkables.CheckerFactory; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; + /** * * @author Root101 (jhernandezb96@gmail.com, +53-5-426-8660)