All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.snice.preconditions.ValidationError Maven / Gradle / Ivy

package io.snice.preconditions;

import io.snice.functional.Either;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import static io.snice.preconditions.PreConditions.assertArgument;
import static io.snice.preconditions.PreConditions.assertNotNull;

/**
 * There are many cases where validation needs to occur, which may yield in errors. E.g., when validating a SIP or
 * a Diameter message, you may discover that they are missing mandatory headers (SIP) or AVPs (Diameter). However,
 * instead of throwing exceptions, generating a {@link ValidationError} wrapped in an {@link Either} allows for
 * a more functional approach in handling these validation errors.
 */
public interface ValidationError {

    static  ValidationError of(T error) {
        assertNotNull(error);
        return new DefaultValidationError<>(List.of(error));
    }

    static  ValidationError of(T... errors) {
        assertNotNull(errors);
        assertArgument(errors.length > 0, "The list of errors cannot be empty");
        return new DefaultValidationError<>(List.of(errors));
    }

    /**
     * Convenience method for appending errors to a {@link ValidationError} that, if null, will
     * first be created.
     *
     * @param v the {@link ValidationError} to append the given error to, or if it is null, a new
     *          one will be created.
     * @param error the error that will be appended to the given {@link ValidationError} or to a new
     *              one if the given one is null.
     * @return a new {@link ValidationError} object that contains the given error as well as any previous
     * errors from the optional {@link ValidationError} passed in.
     */
    static  ValidationError append(ValidationError v, T error) {
        if (v == null) {
            return ValidationError.of(error);
        }

        return v.append(error);
    }

    /**
     * A list of T describing the issues found while validating.
     *
     * @return
     */
    List getErrors();

    /**
     * If more errors are found, you can append them.
     *
     * Note that {@link ValidationError} is a mutable class and as such,
     * the {@link ValidationError} returned will be a different instance
     * than this one and the current one will be left untouched.
     *
     * @param errors
     * @return a new {@link ValidationError} that contains the list of errors from this
     * instance plus the new set of errors.
     */
    ValidationError append(T... errors);

    class DefaultValidationError implements ValidationError {

        private final List errors;

        private DefaultValidationError(List errors) {
            this.errors = errors;
        }

        @Override
        public List getErrors() {
            return errors;
        }

        @Override
        public ValidationError append(T... errors) {
            if (errors == null || errors.length == 0) {
                return this;
            }
            final var l = new ArrayList<>(this.errors);
            for (int i = 0; i < errors.length; ++i) {
                l.add(errors[i]);
            }
            return new DefaultValidationError<>(Collections.unmodifiableList(l));
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy