instances, final ValidationResul
}
/**
- * {@link #apply(Object) AbstractValidator}
+ * Applies validation rules to an instance and returns a boolean result.
+ *
+ * This method is typically called internally during the validation process.
+ * It ensures rules are initialized, sets up the validation context, and
+ * processes all rules against the given instance.
+ *
+ *
+ * @param instance the object instance to validate
+ * @return true if all validation rules pass, false if any rule fails
*/
@Override
public boolean apply(final T instance) {
@@ -163,7 +319,17 @@ public boolean apply(final T instance) {
}
/**
- * {@link #ruleFor(Function) AbstractValidator}
+ * Creates a validation rule for a specific property of the validated object.
+ *
+ * This method starts a fluent chain for defining validation rules that apply
+ * to a property extracted from the validated object using the provided function.
+ * The property name will be automatically derived from the function if possible.
+ *
+ *
+ * @param the type of the property being validated
+ * @param function a function that extracts the property value from the validated object
+ * @return a RuleBuilderProperty for chaining additional validation constraints
+ * @throws NullPointerException if function is null
*/
@Override
public
RuleBuilderProperty ruleFor(final Function function) {
@@ -173,7 +339,19 @@ public RuleBuilderProperty ruleFor(final Function function) {
}
/**
- * {@link #ruleFor(String, Function) AbstractValidator}
+ * Creates a validation rule for a named property of the validated object.
+ *
+ * This method starts a fluent chain for defining validation rules that apply
+ * to a property extracted from the validated object. The field name is explicitly
+ * provided and will be used in error messages and validation context.
+ *
+ *
+ * @param the type of the property being validated
+ * @param fieldName the name of the field being validated (used in error messages)
+ * @param function a function that extracts the property value from the validated object
+ * @return a RuleBuilderProperty for chaining additional validation constraints
+ * @throws NullPointerException if fieldName or function is null
+ * @throws IllegalArgumentException if fieldName is empty
*/
@Override
public
RuleBuilderProperty ruleFor(final String fieldName, final Function function) {
@@ -183,7 +361,19 @@ public RuleBuilderProperty ruleFor(final String fieldName, final Funct
}
/**
- * {@link #ruleForEach(String, Function) AbstractValidator}
+ * Creates validation rules for each element in a collection property.
+ *
+ * This method starts a fluent chain for defining validation rules that apply
+ * to each element of a collection extracted from the validated object.
+ * The field name is explicitly provided for error reporting.
+ *
+ *
+ * @param the type of elements in the collection being validated
+ * @param fieldName the name of the collection field being validated
+ * @param function a function that extracts the collection from the validated object
+ * @return a RuleBuilderCollection for chaining additional validation constraints
+ * @throws NullPointerException if fieldName or function is null
+ * @throws IllegalArgumentException if fieldName is empty
*/
@Override
public
RuleBuilderCollection ruleForEach(final String fieldName, final Function> function) {
@@ -193,7 +383,17 @@ public RuleBuilderCollection ruleForEach(final String fieldName, final
}
/**
- * {@link #ruleForEach(Function) AbstractValidator}
+ * Creates validation rules for each element in a collection property.
+ *
+ * This method starts a fluent chain for defining validation rules that apply
+ * to each element of a collection extracted from the validated object.
+ * The field name will be automatically derived from the function if possible.
+ *
+ *
+ * @param the type of elements in the collection being validated
+ * @param function a function that extracts the collection from the validated object
+ * @return a RuleBuilderCollection for chaining additional validation constraints
+ * @throws NullPointerException if function is null
*/
@Override
public
RuleBuilderCollection ruleForEach(final Function> function) {
diff --git a/src/main/java/br/com/fluentvalidator/annotation/CleanValidationContextException.java b/src/main/java/br/com/fluentvalidator/annotation/CleanValidationContextException.java
deleted file mode 100644
index a620a8d..0000000
--- a/src/main/java/br/com/fluentvalidator/annotation/CleanValidationContextException.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2019 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package br.com.fluentvalidator.annotation;
-
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-@Inherited
-@Target(METHOD)
-@Retention(RUNTIME)
-public @interface CleanValidationContextException {
-
-}
diff --git a/src/main/java/br/com/fluentvalidator/aspect/ValidationExceptionAdvice.java b/src/main/java/br/com/fluentvalidator/aspect/ValidationExceptionAdvice.java
deleted file mode 100644
index 0fd41e5..0000000
--- a/src/main/java/br/com/fluentvalidator/aspect/ValidationExceptionAdvice.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2019 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package br.com.fluentvalidator.aspect;
-
-import org.aspectj.lang.annotation.AfterThrowing;
-import org.aspectj.lang.annotation.Aspect;
-
-import br.com.fluentvalidator.annotation.CleanValidationContextException;
-import br.com.fluentvalidator.context.ValidationContext;
-
-@Aspect
-public class ValidationExceptionAdvice {
-
- @AfterThrowing("execution(* *(..)) && @annotation(cleanValidationContextException)")
- public void afterThrowing(final CleanValidationContextException cleanValidationContextException) {
- ValidationContext.remove();
- }
-
-}
diff --git a/src/main/java/br/com/fluentvalidator/context/Error.java b/src/main/java/br/com/fluentvalidator/context/Error.java
index 89d4a4a..ca58ffa 100644
--- a/src/main/java/br/com/fluentvalidator/context/Error.java
+++ b/src/main/java/br/com/fluentvalidator/context/Error.java
@@ -16,6 +16,25 @@
package br.com.fluentvalidator.context;
+/**
+ * Represents a validation error context, encapsulating details about a failed validation,
+ * including the field name, error message, error code, and the attempted value.
+ *
+ * Instances of {@code Error} are immutable and can be created using the static {@link #create(String, String, String, Object)} method.
+ *
+ *
+ *
+ * - {@code field}: The name of the field that failed validation.
+ * - {@code message}: The error message describing the validation failure.
+ * - {@code code}: The error code associated with the validation error.
+ * - {@code attemptedValue}: The value that was attempted and caused the error.
+ *
+ *
+ * Example usage:
+ *
+ * Error error = Error.create("username", "Username must not be empty", "USR_001", null);
+ *
+ */
public class Error {
private final String message;
@@ -27,17 +46,26 @@ public class Error {
private final String code;
/**
+ * Creates a new Error instance with the specified field, message, code, and attempted value.
*
- * @param field
- * @param message
- * @param code
- * @param attemptedValue
- * @return
+ * @param field the name of the field that failed validation
+ * @param message the validation error message
+ * @param code the error code associated with this validation error
+ * @param attemptedValue the value that was attempted and failed validation
+ * @return a new Error instance with the provided parameters
*/
public static Error create(final String field, final String message, final String code, final Object attemptedValue) {
return new Error(field, message, code, attemptedValue);
}
+ /**
+ * Constructs an {@code Error} instance with the specified field, message, code, and attempted value.
+ *
+ * @param field the name of the field where the error occurred
+ * @param message the error message describing the validation failure
+ * @param code the error code associated with the validation error
+ * @param attemptedValue the value that was attempted and caused the error
+ */
protected Error(final String field, final String message, final String code, final Object attemptedValue) {
this.field = field;
this.message = message;
@@ -46,37 +74,47 @@ protected Error(final String field, final String message, final String code, fin
}
/**
+ * Returns the name of the field associated with this error.
*
- * @return
+ * @return the field name as a {@code String}
*/
public String getField() {
return field;
}
/**
+ * Returns the error message associated with this error context.
*
- * @return
+ * @return the error message as a {@code String}
*/
public String getMessage() {
return message;
}
/**
+ * Returns the error code associated with this error.
*
- * @return
+ * @return the error code as a {@code String}
*/
public String getCode() {
return code;
}
/**
+ * Returns the value that was attempted during validation.
*
- * @return
+ * @return the attempted value, which may be null if not set
*/
public Object getAttemptedValue() {
return attemptedValue;
}
+ /**
+ * Returns a string representation of the Error object, including the message,
+ * field, attempted value, and code properties.
+ *
+ * @return a formatted string describing the Error instance
+ */
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
diff --git a/src/main/java/br/com/fluentvalidator/context/ProcessorContext.java b/src/main/java/br/com/fluentvalidator/context/ProcessorContext.java
index 243d25d..818f269 100644
--- a/src/main/java/br/com/fluentvalidator/context/ProcessorContext.java
+++ b/src/main/java/br/com/fluentvalidator/context/ProcessorContext.java
@@ -25,13 +25,19 @@ public final class ProcessorContext {
private static final ThreadLocal threadLocal = new ThreadLocal<>();
+ /**
+ * Private constructor to prevent instantiation of {@code ProcessorContext} from outside the class.
+ * Ensures that instances can only be created internally, typically for singleton or factory patterns.
+ */
private ProcessorContext() {
super();
}
/**
+ * Retrieves the current {@link Context} instance associated with the calling thread.
+ * If no {@link Context} exists for the thread, a new instance is created and set.
*
- * @return
+ * @return the {@link Context} instance for the current thread
*/
public static Context get() {
if (Objects.isNull(threadLocal.get())) {
@@ -41,35 +47,68 @@ public static Context get() {
}
/**
- *
+ * Removes the current thread's value for the processor context from the ThreadLocal storage.
+ * This method should be called to clean up resources and avoid potential memory leaks
+ * when the context is no longer needed in the current thread.
*/
public static void remove() {
threadLocal.remove();
}
/**
- * Context of processor
+ * Context is a utility class that manages a stack of counters using {@link AtomicInteger}.
+ * It provides methods to create, remove, increment, and retrieve the current counter value.
+ * The stack is thread-safe, allowing concurrent access.
+ *
+ *
+ * - {@link #create()} - Pushes a new counter onto the stack, initialized to zero.
+ * - {@link #remove()} - Removes the top counter from the stack if it exists.
+ * - {@link #inc()} - Increments the top counter if the stack is not empty.
+ * - {@link #get()} - Retrieves the value of the top counter, or zero if the stack is empty.
+ *
*/
public static final class Context implements AutoCloseable {
private final Deque stackCounter = new ConcurrentLinkedDeque<>();
+ /**
+ * Initializes a new processing context by pushing a fresh {@link AtomicInteger} with value 0 onto the stack counter.
+ * This method is typically used to start a new validation or processing scope.
+ */
public void create() {
stackCounter.push(new AtomicInteger(0));
}
+ /**
+ * Removes the top element from the {@code stackCounter} if it is not empty.
+ * This method is typically used to manage the stack state within the processor context,
+ * ensuring that elements are only removed when available.
+ */
public void remove() {
if (!stackCounter.isEmpty()) {
stackCounter.pop();
}
}
+ /**
+ * Increments the top value of the stack counter if the stack is not empty.
+ *
+ * This method checks if the {@code stackCounter} is not empty and, if so,
+ * increments the value at the top of the stack using {@code incrementAndGet()}.
+ *
+ */
public void inc() {
if (!stackCounter.isEmpty()) {
stackCounter.peek().incrementAndGet();
}
}
+ /**
+ * Retrieves the current value from the stack counter.
+ * If the stack counter is empty, returns {@code 0}.
+ *
+ * @return the current value of the stack counter, or {@code 0} if empty
+ */
public Integer get() {
return stackCounter.isEmpty() ? 0 : stackCounter.peek().get();
}
diff --git a/src/main/java/br/com/fluentvalidator/context/ValidationContext.java b/src/main/java/br/com/fluentvalidator/context/ValidationContext.java
index d3c84f7..60dc802 100644
--- a/src/main/java/br/com/fluentvalidator/context/ValidationContext.java
+++ b/src/main/java/br/com/fluentvalidator/context/ValidationContext.java
@@ -23,17 +23,38 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
+/**
+ * Utility class for managing validation context using thread-local storage.
+ *
+ * Provides access to a thread-local {@link Context} instance, which holds validation properties and errors.
+ *
+ *
+ *
+ * - {@link #get()} - Retrieves the current thread's validation context, creating one if necessary.
+ * - {@link #remove()} - Removes the validation context from the current thread.
+ *
+ *
+ *
+ * The nested {@link Context} class allows storing arbitrary properties and collecting validation errors.
+ *
+ */
public final class ValidationContext {
private static final ThreadLocal threadLocal = new ThreadLocal<>();
+ /**
+ * Private constructor to prevent instantiation of {@code ValidationContext}.
+ * This ensures that the class can only be used in a static context or through controlled access.
+ */
private ValidationContext() {
super();
}
/**
+ * Retrieves the current {@link Context} instance associated with the calling thread.
+ * If no instance exists, a new {@link Context} is created and associated with the thread.
*
- * @return
+ * @return the {@link Context} instance for the current thread
*/
public static Context get() {
if (Objects.isNull(threadLocal.get())) {
@@ -43,14 +64,31 @@ public static Context get() {
}
/**
- *
+ * Removes the current {@link ValidationContext} instance from the thread-local storage.
+ * This method should be called to clean up resources and avoid memory leaks
+ * after validation operations are completed in the current thread.
*/
public static void remove() {
threadLocal.remove();
}
/**
- * Context of validation
+ * Represents a validation context for storing properties and errors during validation.
+ *
+ * This class maintains a thread-safe map of properties and a queue of validation errors.
+ * It provides methods to add errors, set and retrieve properties, and obtain the validation result.
+ *
+ *
+ *
+ * - {@link #addErrors(Collection)} - Adds a collection of validation errors to the context.
+ * - {@link #setProperty(String, Object)} - Sets a property in the context.
+ * - {@link #getProperty(String, Class)} - Retrieves a property from the context, cast to the specified type.
+ * - {@link #getValidationResult()} - Returns the validation result based on the collected errors.
+ *
+ *
+ *
+ * This class is intended for internal use within the validation framework.
+ *
*/
public static final class Context implements AutoCloseable {
@@ -59,20 +97,20 @@ public static final class Context implements AutoCloseable {
private final Queue errors = new ConcurrentLinkedQueue<>();
/**
+ * Adds a collection of {@link Error} objects to the current list of errors.
*
- * @param field
- * @param message
- * @param code
- * @param attemptedValue
+ * @param errs the collection of errors to be added
*/
public void addErrors(final Collection errs) {
errs.stream().forEach(errors::add);
}
/**
+ * Sets a property in the validation context with the specified key and value.
+ * If the property key is not {@code null}, it will be added or updated in the context.
*
- * @param property
- * @param value
+ * @param property the key of the property to set; must not be {@code null}
+ * @param value the value to associate with the property key
*/
public void setProperty(final String property, final Object value) {
if (Objects.nonNull(property)) {
@@ -81,8 +119,14 @@ public void setProperty(final String property, final Object value) {
}
/**
+ * Retrieves the validation result for the current context.
+ *
+ * This method clears the thread-local validation context and returns a {@link ValidationResult}
+ * indicating whether validation errors were found. If no errors are present, {@link ValidationResult#ok()}
+ * is returned; otherwise, {@link ValidationResult#fail(java.util.List)} is returned with the list of errors.
+ *
*
- * @return
+ * @return the {@link ValidationResult} representing the outcome of the validation.
*/
public ValidationResult getValidationResult() {
ValidationContext.remove();
@@ -90,10 +134,13 @@ public ValidationResult getValidationResult() {
}
/**
+ * Retrieves the value of a property by its name and casts it to the specified type.
*
- * @param property
- * @param clazz
- * @return
+ * @param property the name of the property to retrieve
+ * @param clazz the class object representing the desired return type
+ * @param the type of the property value
+ * @return the property value cast to the specified type, or {@code null} if the property does not exist
+ * @throws ClassCastException if the property value cannot be cast to the specified type
*/
public
P getProperty(final String property, final Class
clazz) {
return clazz.cast(properties.getOrDefault(property, null));
diff --git a/src/main/java/br/com/fluentvalidator/context/ValidationResult.java b/src/main/java/br/com/fluentvalidator/context/ValidationResult.java
index 3345f80..311e3ac 100644
--- a/src/main/java/br/com/fluentvalidator/context/ValidationResult.java
+++ b/src/main/java/br/com/fluentvalidator/context/ValidationResult.java
@@ -20,8 +20,16 @@
import java.util.Collection;
import java.util.Collections;
import java.util.Optional;
+
import br.com.fluentvalidator.exception.ValidationException;
+/**
+ * Represents the result of a validation operation, containing the validation status
+ * and any associated error messages.
+ *
+ *
This class is immutable and thread-safe. It provides factory methods to create
+ * instances representing successful or failed validation results.
+ */
public final class ValidationResult {
private final boolean valid;
@@ -29,30 +37,44 @@ public final class ValidationResult {
private final Collection errors;
/**
+ * Creates a successful validation result with no errors.
*
- * @return
+ * @return a ValidationResult instance representing a successful validation
*/
public static ValidationResult ok() {
return new ValidationResult(true, new ArrayList<>());
}
/**
+ * Creates a failed validation result with the specified error messages.
*
- * @param messages
- * @return
+ * @param messages the collection of error messages; if null, an empty collection is used
+ * @return a ValidationResult instance representing a failed validation
*/
public static ValidationResult fail(final Collection messages) {
return new ValidationResult(false, Optional.ofNullable(messages).orElse(new ArrayList<>()));
}
+ /**
+ * Private constructor to create a ValidationResult instance.
+ *
+ * @param valid indicates whether the validation was successful
+ * @param messages the collection of error messages
+ */
private ValidationResult(final boolean valid, final Collection messages) {
this.valid = valid;
errors = Collections.unmodifiableCollection(messages);
}
/**
+ * Throws a validation exception if the validation result is invalid.
*
- * @param clazz
+ * This method provides a convenient way to convert validation failures
+ * into exceptions for error handling purposes.
+ *
+ * @param the type of ValidationException to throw
+ * @param clazz the class of the ValidationException to instantiate and throw
+ * @throws ValidationException if the validation result is invalid
*/
public void isInvalidThrow(final Class clazz) {
if (!isValid()) {
@@ -61,21 +83,34 @@ public void isInvalidThrow(final Class clazz)
}
/**
+ * Checks whether the validation was successful.
*
- * @return
+ * @return {@code true} if the validation was successful, {@code false} otherwise
*/
public boolean isValid() {
return valid;
}
/**
+ * Returns the collection of validation errors.
+ *
+ * The returned collection is unmodifiable. If the validation was successful,
+ * this collection will be empty.
*
- * @return
+ * @return an unmodifiable collection of validation errors
*/
public Collection getErrors() {
return errors;
}
+ /**
+ * Returns a string representation of this ValidationResult.
+ *
+ * The string representation includes the validation status and
+ * the collection of errors.
+ *
+ * @return a string representation of this ValidationResult
+ */
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
diff --git a/src/main/java/br/com/fluentvalidator/exception/ValidationException.java b/src/main/java/br/com/fluentvalidator/exception/ValidationException.java
index 3f1e7b7..514e15a 100644
--- a/src/main/java/br/com/fluentvalidator/exception/ValidationException.java
+++ b/src/main/java/br/com/fluentvalidator/exception/ValidationException.java
@@ -21,39 +21,84 @@
import br.com.fluentvalidator.context.ValidationContext;
import br.com.fluentvalidator.context.ValidationResult;
+/**
+ * Abstract base class for validation exceptions in the FluentValidator framework.
+ *
+ * This class provides a foundation for creating custom validation exceptions that
+ * carry validation results. It extends {@link RuntimeException} and includes
+ * factory methods for creating instances of validation exception subclasses.
+ *
+ */
public abstract class ValidationException extends RuntimeException {
private static final long serialVersionUID = 2274879814700248645L;
private final transient ValidationResult validationResult;
+ /**
+ * Constructs a new ValidationException with the specified validation result.
+ *
+ * The exception message is automatically generated from the validation result's
+ * string representation.
+ *
+ *
+ * @param validationResult the validation result containing error details
+ * @throws NullPointerException if validationResult is null
+ */
protected ValidationException(final ValidationResult validationResult) {
super(validationResult.toString());
this.validationResult = validationResult;
}
/**
+ * Returns the validation result associated with this exception.
+ *
+ * The validation result contains detailed information about validation
+ * errors that occurred during the validation process.
+ *
*
- * @return
+ * @return the validation result, never null
*/
public ValidationResult getValidationResult() {
return validationResult;
}
/**
+ * Creates a new instance of the specified validation exception class using
+ * the current validation context's result.
+ *
+ * This is a convenience method that retrieves the validation result from
+ * the current {@link ValidationContext} and creates an exception instance.
+ *
*
- * @param exceptionClass
- * @return
+ * @param the type of validation exception to create
+ * @param exceptionClass the class of the validation exception to instantiate
+ * @return a new RuntimeException instance of the specified type
+ * @throws RuntimeException if the exception class doesn't have the required constructor
+ * or if instantiation fails
+ * @see #create(Class, ValidationResult)
*/
public static RuntimeException create(final Class exceptionClass) {
return create(exceptionClass, ValidationContext.get().getValidationResult());
}
/**
+ * Creates a new instance of the specified validation exception class with
+ * the provided validation result.
+ *
+ * This method uses reflection to instantiate the exception class. The target
+ * class must have a constructor that accepts a single {@link ValidationResult}
+ * parameter.
+ *
*
- * @param exceptionClass
- * @param validationResult
- * @return
+ * @param the type of validation exception to create
+ * @param exceptionClass the class of the validation exception to instantiate
+ * @param validationResult the validation result to associate with the exception
+ * @return a new RuntimeException instance of the specified type
+ * @throws RuntimeException if the exception class doesn't have a constructor
+ * accepting ValidationResult, or if instantiation fails
+ * due to security restrictions, illegal access, or
+ * invocation target exceptions
*/
public static RuntimeException create(final Class exceptionClass, final ValidationResult validationResult) {
try {
diff --git a/src/main/java/br/com/fluentvalidator/function/FunctionBuilder.java b/src/main/java/br/com/fluentvalidator/function/FunctionBuilder.java
index 12bce84..f2c0b61 100644
--- a/src/main/java/br/com/fluentvalidator/function/FunctionBuilder.java
+++ b/src/main/java/br/com/fluentvalidator/function/FunctionBuilder.java
@@ -19,13 +19,39 @@
import java.util.Objects;
import java.util.function.Function;
+/**
+ * A builder wrapper for {@link Function} that provides null-safe function composition
+ * and execution. This class wraps a function and ensures that null inputs are handled
+ * gracefully by returning null instead of throwing exceptions.
+ *
+ * The FunctionBuilder provides a fluent API for creating and composing functions
+ * while maintaining null safety throughout the chain of operations.
+ *
+ * Example usage:
+ * {@code
+ * Function stringToLength = FunctionBuilder.of(String::length);
+ * Integer result = stringToLength.apply(null); // Returns null instead of NPE
+ *
+ * Function composed = FunctionBuilder.of(String::toLowerCase)
+ * .andThen(s -> s + "!");
+ * }
+ *
+ * @param the type of the input to the function
+ * @param the type of the result of the function
+ */
public final class FunctionBuilder implements Function {
+ /**
+ * The wrapped function that will be executed when apply is called.
+ */
private final Function function;
/**
+ * Private constructor to create a new FunctionBuilder instance.
+ * Use {@link #of(Function)} to create instances.
*
- * @param function
+ * @param function the function to wrap, must not be null
+ * @throws NullPointerException if function is null
*/
private FunctionBuilder(final Function function) {
this.function = function;
@@ -35,16 +61,58 @@ public static Function of(final Function function) {
return new FunctionBuilder<>(function);
}
+ /**
+ * Applies this function to the given argument with null-safe behavior.
+ *
+ * If the input value is null, this method returns null without
+ * calling the wrapped function. Otherwise, it applies the wrapped
+ * function to the input value.
+ *
+ * @param value the function argument
+ * @return the function result, or null if the input value is null
+ */
@Override
public O apply(final I value) {
return Objects.nonNull(value) ? function.apply(value) : null;
}
+ /**
+ * Returns a composed function that first applies this function to its input,
+ * and then applies the {@code after} function to the result, maintaining
+ * null-safe behavior throughout the composition.
+ *
+ * If either this function or the after function would receive a null input,
+ * the entire composition returns null without executing subsequent functions.
+ *
+ * @param the type of output of the after function, and of the composed function
+ * @param after the function to apply after this function is applied
+ * @return a composed function that first applies this function and then applies the
+ * {@code after} function
+ * @throws NullPointerException if after is null
+ *
+ * @see Function#andThen(Function)
+ */
@Override
public Function andThen(final Function super O, ? extends V> after) {
return of(i -> of(after).apply(this.apply(i)));
}
+ /**
+ * Returns a composed function that first applies the {@code before} function to
+ * its input, and then applies this function to the result, maintaining null-safe
+ * behavior throughout the composition.
+ *
+ * If either the before function or this function would receive a null input,
+ * the entire composition returns null without executing subsequent functions.
+ *
+ * @param the type of input to the before function, and to the composed function
+ * @param before the function to apply before this function is applied
+ * @return a composed function that first applies the {@code before} function and
+ * then applies this function
+ * @throws NullPointerException if before is null
+ *
+ * @see Function#compose(Function)
+ */
@Override
public Function compose(final Function super V, ? extends I> before) {
return of(v -> this.apply(of(before).apply(v)));
diff --git a/src/main/java/br/com/fluentvalidator/handler/HandlerInvalidField.java b/src/main/java/br/com/fluentvalidator/handler/HandlerInvalidField.java
index ac036eb..c040a5d 100644
--- a/src/main/java/br/com/fluentvalidator/handler/HandlerInvalidField.java
+++ b/src/main/java/br/com/fluentvalidator/handler/HandlerInvalidField.java
@@ -20,12 +20,64 @@
import java.util.Collections;
import br.com.fluentvalidator.context.Error;
+/**
+ * Interface for handling invalid field validation scenarios.
+ *
+ * This interface provides a contract for implementing custom handlers that process
+ * validation failures for specific field types. Implementations can define custom
+ * logic to generate appropriate error messages or perform additional processing
+ * when field validation fails.
+ *
+ *
+ * The interface supports two handling approaches:
+ *
+ * - Simple handling based only on the attempted value
+ * - Context-aware handling that considers both the object instance and attempted value
+ *
+ *
+ *
+ * @param the type of the field value being validated
+ */
public interface HandlerInvalidField
{
+ /**
+ * Handles validation failure for a field with the given attempted value.
+ *
+ * This method is called when field validation fails and provides an opportunity
+ * to generate custom error messages or perform additional processing based on
+ * the attempted value.
+ *
+ *
+ * The default implementation returns an empty collection, indicating no errors
+ * should be added beyond the standard validation failure.
+ *
+ *
+ * @param attemptedValue the value that failed validation, may be {@code null}
+ * @return a collection of {@link Error} objects representing validation errors,
+ * never {@code null} but may be empty
+ */
default Collection handle(final P attemptedValue) {
return Collections.emptyList();
}
+ /**
+ * Handles validation failure for a field with context of the containing object instance.
+ *
+ * This method provides additional context by including the object instance that
+ * contains the field being validated. This allows for more sophisticated error
+ * handling that can consider the state of the entire object.
+ *
+ *
+ * The default implementation delegates to {@link #handle(Object)} with only
+ * the attempted value, ignoring the instance context.
+ *
+ *
+ * @param instance the object instance containing the field being validated,
+ * may be {@code null}
+ * @param attemptedValue the value that failed validation, may be {@code null}
+ * @return a collection of {@link Error} objects representing validation errors,
+ * never {@code null} but may be empty
+ */
default Collection handle(final Object instance, final P attemptedValue) {
return handle(attemptedValue);
}
diff --git a/src/main/java/br/com/fluentvalidator/predicate/CollectionPredicate.java b/src/main/java/br/com/fluentvalidator/predicate/CollectionPredicate.java
index c1362ef..9e06ad5 100644
--- a/src/main/java/br/com/fluentvalidator/predicate/CollectionPredicate.java
+++ b/src/main/java/br/com/fluentvalidator/predicate/CollectionPredicate.java
@@ -28,13 +28,19 @@
import java.util.function.Function;
import java.util.function.Predicate;
+/**
+ * Utility class providing predicate methods for validating collections.
+ * This class contains static methods that return predicates for common collection validation scenarios
+ * such as checking if a collection is empty, contains specific items, or has a certain size.
+ */
public final class CollectionPredicate {
/**
+ * Creates a predicate that tests if a collection is empty (null or has no elements).
*
- * @param
- * @param
- * @return
+ * @param the type of elements in the collection
+ * @param the type of collection that extends Collection<E>
+ * @return a predicate that returns true if the collection is null or empty
*/
public static > Predicate empty() {
return PredicateBuilder.from(is(nullValue()))
@@ -42,11 +48,12 @@ public static > Predicate empty() {
}
/**
+ * Creates a predicate that tests if a collection extracted from an object is empty.
*
- * @param
- * @param
- * @param source
- * @return
+ * @param the type of the object being tested
+ * @param the type of elements in the collection
+ * @param source a function that extracts a collection from the object
+ * @return a predicate that returns true if the extracted collection is null or empty
*/
public static Predicate empty(final Function> source) {
return PredicateBuilder.from(is(nullValue()))
@@ -55,11 +62,12 @@ public static Predicate empty(final Function> source)
}
/**
+ * Creates a predicate that tests if a collection contains any of the specified objects.
*
- * @param
- * @param
- * @param objects
- * @return
+ * @param the type of elements in the collection
+ * @param the type of collection that extends Collection<E>
+ * @param objects the collection of objects to check for
+ * @return a predicate that returns true if the collection contains any of the specified objects
*/
public static > Predicate hasAny(final Collection objects) {
return PredicateBuilder.from(not(nullValue()))
@@ -68,11 +76,12 @@ public static > Predicate hasAny(final Collection<
}
/**
+ * Creates a predicate that tests if a collection contains any of the specified objects from an array.
*
- * @param
- * @param
- * @param objects
- * @return
+ * @param the type of elements in the collection
+ * @param the type of collection that extends Collection<E>
+ * @param objects the array of objects to check for
+ * @return a predicate that returns true if the collection contains any of the specified objects
*/
public static > Predicate hasAny(final E[] objects) {
return PredicateBuilder.from(not(nullValue()))
@@ -81,12 +90,13 @@ public static > Predicate hasAny(final E[] objects
}
/**
+ * Creates a predicate that tests if a collection extracted from an object contains any of the specified objects.
*
- * @param
- * @param
- * @param source
- * @param objects
- * @return
+ * @param the type of the object being tested
+ * @param the type of elements in the collection
+ * @param source a function that extracts a collection from the object
+ * @param objects the collection of objects to check for
+ * @return a predicate that returns true if the extracted collection contains any of the specified objects
*/
public static Predicate hasAny(final Function> source, final Collection objects) {
return PredicateBuilder.from(not(nullValue()))
@@ -94,12 +104,13 @@ public static Predicate hasAny(final Function> source
}
/**
+ * Creates a predicate that tests if a collection extracted from an object contains any of the specified objects from an array.
*
- * @param
- * @param
- * @param source
- * @param objects
- * @return
+ * @param the type of the object being tested
+ * @param the type of elements in the collection
+ * @param source a function that extracts a collection from the object
+ * @param objects the array of objects to check for
+ * @return a predicate that returns true if the extracted collection contains any of the specified objects
*/
public static Predicate hasAny(final Function> source, final E[] objects) {
return PredicateBuilder.from(not(nullValue()))
@@ -121,7 +132,7 @@ public static Predicate hasAny(final Function> source
* @param type of exam class
* @param object the object to compare against the objects provided by the
* examined {@link Collection}
- * @return {@link Predicate}
+ * @return {@link Predicate} that returns true if the collection contains the specified object
*/
public static > Predicate hasItem(final E object) {
return PredicateBuilder.from(not(nullValue()))
@@ -129,12 +140,13 @@ public static > Predicate hasItem(final E object)
}
/**
+ * Creates a predicate that tests if a collection extracted from an object contains the specified item.
*
- * @param
- * @param
- * @param source
- * @param object
- * @return
+ * @param the type of the object being tested
+ * @param the type of elements in the collection
+ * @param source a function that extracts a collection from the object
+ * @param object the object to check for in the collection
+ * @return a predicate that returns true if the extracted collection contains the specified object
*/
public static Predicate hasItem(final Function> source, final E object) {
return PredicateBuilder.from(not(nullValue()))
@@ -142,11 +154,12 @@ public static Predicate hasItem(final Function> sourc
}
/**
+ * Creates a predicate that tests if a collection contains all of the specified objects.
*
- * @param
- * @param
- * @param objects
- * @return
+ * @param the type of elements in the collection
+ * @param the type of collection that extends Collection<E>
+ * @param objects the collection of objects that must all be present
+ * @return a predicate that returns true if the collection contains all specified objects
*/
public static > Predicate hasItems(final Collection objects) {
return PredicateBuilder.from(not(nullValue()))
@@ -155,11 +168,12 @@ public static > Predicate hasItems(final Collectio
}
/**
- *
- * @param
- * @param
- * @param objects
- * @return
+ * Creates a predicate that tests if a collection contains all of the specified objects from an array.
+ *
+ * @param the type of elements in the collection
+ * @param the type of collection that extends Collection<E>
+ * @param objects the array of objects that must all be present
+ * @return a predicate that returns true if the collection contains all specified objects
*/
public static > Predicate hasItems(final E[] objects) {
return PredicateBuilder.from(not(nullValue()))
@@ -168,12 +182,13 @@ public static > Predicate hasItems(final E[] objec
}
/**
- *
- * @param
- * @param
- * @param source
- * @param objects
- * @return
+ * Creates a predicate that tests if a collection extracted from an object contains all of the specified objects.
+ *
+ * @param the type of the object being tested
+ * @param the type of elements in the collection
+ * @param source a function that extracts a collection from the object
+ * @param objects the collection of objects that must all be present
+ * @return a predicate that returns true if the extracted collection contains all specified objects
*/
public static Predicate hasItems(final Function> source, final Collection objects) {
return PredicateBuilder.from(not(nullValue()))
@@ -181,12 +196,13 @@ public static Predicate hasItems(final Function> sour
}
/**
+ * Creates a predicate that tests if a collection extracted from an object contains all of the specified objects from an array.
*
- * @param
- * @param
- * @param source
- * @param objects
- * @return
+ * @param the type of the object being tested
+ * @param the type of elements in the collection
+ * @param source a function that extracts a collection from the object
+ * @param objects the array of objects that must all be present
+ * @return a predicate that returns true if the extracted collection contains all specified objects
*/
public static Predicate hasItems(final Function> source, final E[] objects) {
return PredicateBuilder.from(not(nullValue()))
@@ -194,12 +210,13 @@ public static Predicate hasItems(final Function> sour
}
/**
+ * Creates a predicate that tests if a collection extracted from an object has a size equal to a dynamically computed value.
*
- * @param
- * @param
- * @param source
- * @param size
- * @return
+ * @param the type of the object being tested
+ * @param the type of elements in the collection
+ * @param source a function that extracts a collection from the object
+ * @param size a function that computes the expected size from the object
+ * @return a predicate that returns true if the extracted collection has the computed size
*/
public static Predicate hasSize(final Function> source, final Function size) {
return PredicateBuilder.from(not(nullValue()))
@@ -209,12 +226,13 @@ public static Predicate hasSize(final Function> sourc
}
/**
+ * Creates a predicate that tests if a collection extracted from an object has a specific size.
*
- * @param
- * @param
- * @param source
- * @param size
- * @return
+ * @param the type of the object being tested
+ * @param the type of elements in the collection
+ * @param source a function that extracts a collection from the object
+ * @param size the expected size of the collection
+ * @return a predicate that returns true if the extracted collection has the specified size
*/
public static Predicate hasSize(final Function> source, final Integer size) {
return PredicateBuilder.from(not(nullValue()))
@@ -223,11 +241,12 @@ public static Predicate hasSize(final Function> sourc
}
/**
+ * Creates a predicate that tests if a collection has a specific size.
*
- * @param
- * @param
- * @param size
- * @return
+ * @param the type of elements in the collection
+ * @param the type of collection that extends Collection<E>
+ * @param size the expected size of the collection
+ * @return a predicate that returns true if the collection has the specified size
*/
public static > Predicate hasSize(final Integer size) {
return PredicateBuilder.from(not(nullValue()))
@@ -235,13 +254,14 @@ public static > Predicate hasSize(final Integer si
}
/**
- *
- * @param
- * @param
- * @param source
- * @param min
- * @param max
- * @return
+ * Creates a predicate that tests if a collection extracted from an object has a size between the specified bounds (exclusive).
+ *
+ * @param the type of the object being tested
+ * @param the type of elements in the collection
+ * @param source a function that extracts a collection from the object
+ * @param min the minimum size (exclusive)
+ * @param max the maximum size (exclusive)
+ * @return a predicate that returns true if the extracted collection size is between min and max (exclusive)
*/
public static Predicate hasSizeBetween(final Function> source, final Integer min, final Integer max) {
return PredicateBuilder.from(not(nullValue()))
@@ -250,12 +270,13 @@ public static Predicate hasSizeBetween(final Function
}
/**
- *
- * @param
- * @param
- * @param min
- * @param max
- * @return
+ * Creates a predicate that tests if a collection has a size between the specified bounds (exclusive).
+ *
+ * @param the type of elements in the collection
+ * @param the type of collection that extends Collection<E>
+ * @param min the minimum size (exclusive)
+ * @param max the maximum size (exclusive)
+ * @return a predicate that returns true if the collection size is between min and max (exclusive)
*/
public static > Predicate hasSizeBetween(final Integer min, final Integer max) {
return PredicateBuilder.from(not(nullValue()))
@@ -263,13 +284,14 @@ public static > Predicate hasSizeBetween(final Int
}
/**
+ * Creates a predicate that tests if a collection extracted from an object has a size between the specified bounds (inclusive).
*
- * @param
- * @param
- * @param source
- * @param min
- * @param max
- * @return
+ * @param the type of the object being tested
+ * @param the type of elements in the collection
+ * @param source a function that extracts a collection from the object
+ * @param min the minimum size (inclusive)
+ * @param max the maximum size (inclusive)
+ * @return a predicate that returns true if the extracted collection size is between min and max (inclusive)
*/
public static Predicate hasSizeBetweenInclusive(final Function> source, final Integer min, final Integer max) {
return PredicateBuilder.from(not(nullValue()))
@@ -278,18 +300,22 @@ public static Predicate hasSizeBetweenInclusive(final Function
- * @param
- * @param min
- * @param max
- * @return
+ * @param the type of elements in the collection
+ * @param the type of collection that extends Collection<E>
+ * @param min the minimum size (inclusive)
+ * @param max the maximum size (inclusive)
+ * @return a predicate that returns true if the collection size is between min and max (inclusive)
*/
public static > Predicate hasSizeBetweenInclusive(final Integer min, final Integer max) {
return PredicateBuilder.from(not(nullValue()))
.and(betweenInclusive(Collection::size, min, max));
}
+ /**
+ * Private constructor to prevent instantiation of this utility class.
+ */
private CollectionPredicate() {
super();
}
diff --git a/src/main/java/br/com/fluentvalidator/predicate/ComparablePredicate.java b/src/main/java/br/com/fluentvalidator/predicate/ComparablePredicate.java
index 7fa8e2b..e76a1fd 100644
--- a/src/main/java/br/com/fluentvalidator/predicate/ComparablePredicate.java
+++ b/src/main/java/br/com/fluentvalidator/predicate/ComparablePredicate.java
@@ -456,8 +456,13 @@ public static > Predicate lessThanOrEqual(final Fu
.and(lessThan(source, target).or(equalTo(source, target)));
}
+ /**
+ * Private constructor to prevent instantiation of this utility class.
+ */
private ComparablePredicate() {
super();
}
}
+
+
diff --git a/src/main/java/br/com/fluentvalidator/predicate/DatePredicate.java b/src/main/java/br/com/fluentvalidator/predicate/DatePredicate.java
index cfb4151..d3ff670 100644
--- a/src/main/java/br/com/fluentvalidator/predicate/DatePredicate.java
+++ b/src/main/java/br/com/fluentvalidator/predicate/DatePredicate.java
@@ -269,7 +269,9 @@ public static Predicate dateLessThanOrEqual(final String dateString, fin
.from(dateLessThan(dateString, pattern).or(dateEqualTo(dateString, pattern)));
}
-
+ /**
+ * Private constructor to prevent instantiation of this utility class.
+ */
private DatePredicate() {
super();
}
diff --git a/src/main/java/br/com/fluentvalidator/predicate/DateTimePredicate.java b/src/main/java/br/com/fluentvalidator/predicate/DateTimePredicate.java
index 187a928..29e8b50 100644
--- a/src/main/java/br/com/fluentvalidator/predicate/DateTimePredicate.java
+++ b/src/main/java/br/com/fluentvalidator/predicate/DateTimePredicate.java
@@ -269,6 +269,9 @@ public static Predicate dateTimeLessThanOrEqual(final String dateString,
dateTimeLessThan(dateString, pattern).or(dateTimeEqualTo(dateString, pattern)));
}
+ /**
+ * Private constructor to prevent instantiation of this utility class.
+ */
private DateTimePredicate() {
super();
}
diff --git a/src/main/java/br/com/fluentvalidator/predicate/LocalDatePredicate.java b/src/main/java/br/com/fluentvalidator/predicate/LocalDatePredicate.java
index c13dc11..ea2082b 100644
--- a/src/main/java/br/com/fluentvalidator/predicate/LocalDatePredicate.java
+++ b/src/main/java/br/com/fluentvalidator/predicate/LocalDatePredicate.java
@@ -455,6 +455,9 @@ public static Predicate localDateIsToday(final Function sou
.and(obj -> localDateIsToday().test(source.apply(obj)));
}
+ /**
+ * Private constructor to prevent instantiation of this utility class.
+ */
private LocalDatePredicate() {
super();
}
diff --git a/src/main/java/br/com/fluentvalidator/predicate/LocalDateTimePredicate.java b/src/main/java/br/com/fluentvalidator/predicate/LocalDateTimePredicate.java
index ecec05c..43bdfcb 100644
--- a/src/main/java/br/com/fluentvalidator/predicate/LocalDateTimePredicate.java
+++ b/src/main/java/br/com/fluentvalidator/predicate/LocalDateTimePredicate.java
@@ -506,7 +506,9 @@ public static Predicate localDateTimeBetweenOrEqual(final Function localDateTimeBetweenOrEqual(source, min.apply(obj), max.apply(obj)).test(obj));
}
-
+ /**
+ * Private constructor to prevent instantiation of this utility class.
+ */
private LocalDateTimePredicate() {
super();
}
diff --git a/src/main/java/br/com/fluentvalidator/predicate/LocalTimePredicate.java b/src/main/java/br/com/fluentvalidator/predicate/LocalTimePredicate.java
index ede9fb5..ef26107 100644
--- a/src/main/java/br/com/fluentvalidator/predicate/LocalTimePredicate.java
+++ b/src/main/java/br/com/fluentvalidator/predicate/LocalTimePredicate.java
@@ -390,7 +390,9 @@ public static Predicate localTimeBetweenOrEqual(final Function localTimeBetweenOrEqual(source, min.apply(obj), max.apply(obj)).test(obj));
}
-
+ /**
+ * Private constructor to prevent instantiation of this utility class.
+ */
private LocalTimePredicate() {
super();
}
diff --git a/src/main/java/br/com/fluentvalidator/predicate/LogicalPredicate.java b/src/main/java/br/com/fluentvalidator/predicate/LogicalPredicate.java
index 5e3dd2c..a5315b6 100644
--- a/src/main/java/br/com/fluentvalidator/predicate/LogicalPredicate.java
+++ b/src/main/java/br/com/fluentvalidator/predicate/LogicalPredicate.java
@@ -21,68 +21,100 @@
import java.util.function.Function;
import java.util.function.Predicate;
+/**
+ * Utility class providing logical predicate operations for fluent validation.
+ * This class contains static methods for creating and combining predicates
+ * with logical operations such as negation, boolean evaluation, and identity checks.
+ *
+ * All methods in this class are static and the class cannot be instantiated.
+ */
public final class LogicalPredicate {
-
+
/**
- *
- * @param
- * @param predicate
- * @return
+ * Creates an identity predicate that wraps the given predicate with an additional
+ * always-true condition. This method is primarily used for predicate composition
+ * and fluent API construction.
+ *
+ * @param the type of the input to the predicate
+ * @param predicate the predicate to wrap, must not be null
+ * @return a new predicate that combines the input predicate with an identity check
+ * @throws NullPointerException if predicate is null
*/
static Predicate