Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[bean-validation-dev] Provides a way to implement a dynamic clock provider?

Hi,

I'm trying to implement a solution that dynamically decides which Clock to provide based on the object currently being validated, but the current ClockProvider contract doesn't support this.

I thought about implementing it through the ThreadLocal mechanism, but this would mean that validation relies on threads, and to support asynchronous or concurrent execution, more work would be required, which would increase complexity. I believe the most direct, effective, and simple approach is to pass the current validation object to the ClockProvider, like: change java.time.Clock getClock() to <T> java.time.Clock getClock(T object, Class<?>... groups).


Points to consider for the change:

- Keep functional interface: Ideally, ClockProvider should still be usable with lambda expressions.
- Consider backward compatibility: Think about the pain of code migration, especially with lambda method references.


Proposed Approach 1: Add a New Interface

package jakarta.validation;
import java.time.Clock;
public interface DynamicClockProvider {
    /**
     * Returns the clock which serves as the reference for {@code now}.
     * <p>
     * Ensure that the {@link Clock} used as the reference for {@code now} is obtained
     * for each verification of {@code @Future}, {@code @FutureOrPresent}, {@code @Past},
     * and {@code @PastOrPresent} constraints.
     *
     * @param object object to validate
     * @param groups the group or list of groups targeted for validation (defaults to
     *        {@link jakarta.validation.groups.Default Default})
     * @param <T> the type of the object to validate
     * @return the clock which serves as the reference for {@code now}; must not be
     * {@code null}
     *
     * @since 4.0
     */
    <T> Clock getClock(T object, Class<?>... groups);
}


Proposed Approach 2: Update the ClockProvider

/*
 * Jakarta Validation API
 *
 * License: Apache License, Version 2.0
 * See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
 */
package jakarta.validation;
import java.time.Clock;
/**
 * Contract for obtaining the {@link Clock} used as the reference for {@code now} when
 * validating the {@code @Future}, {@code FutureOrPresent}, {@code Past}, and
 * {@code @PastOrPresent} constraints.
 * <p>
 * The default implementation will return the current system time. Plugging in custom
 * implementations may be useful for instance in batch applications which need to run with a
 * specific logical date, e.g. with yesterday's date when re-running a failed batch job
 * execution.
 * <p>
 * Implementations must be safe for access from several threads at the same time.
 *
 * @author Gunnar Morling
 * @author Guillaume Smet
 * @since 2.0
 */
public interface ClockProvider {
    /**
     * Returns the clock which serves as the reference for {@code now}.
     * <p>
     * Ensure that the {@link Clock} used as the reference for {@code now} is obtained
     * for each verification of {@code @Future}, {@code @FutureOrPresent}, {@code @Past},
     * and {@code @PastOrPresent} constraints.
     *
     * @param object object to validate
     * @param groups the group or list of groups targeted for validation (defaults to
     *        {@link jakarta.validation.groups.Default Default})
     * @param <T> the type of the object to validate
     * @return the clock which serves as the reference for {@code now}; must not be
     * {@code null}
     *
     * @since 4.0
     */
    <T> Clock getClock(T object, Class<?>... groups);
}


What do you think of this? I would greatly appreciate your feedback and any other ideas you might have.

Kind regards,
Xi Minghui


Back to the top