io.github.mmm.validation.collection.AbstractMapValidatorBuilder Maven / Gradle / Ivy
The newest version!
/* Copyright (c) The m-m-m Team, Licensed under the Apache License, Version 2.0
* http://www.apache.org/licenses/LICENSE-2.0 */
package io.github.mmm.validation.collection;
import java.util.Map;
import java.util.function.BiFunction;
import io.github.mmm.base.range.Range;
import io.github.mmm.base.range.RangeType;
import io.github.mmm.validation.AbstractValidator;
import io.github.mmm.validation.Validator;
import io.github.mmm.validation.main.ContainerValidatorBuilder;
import io.github.mmm.validation.main.ObjectValidatorBuilder;
import io.github.mmm.validation.main.ObjectValidatorBuilderFactory;
/**
* The abstract base for a {@link ObjectValidatorBuilder builder} of {@link AbstractValidator} for {@link Map} values.
*
* @param the generic type of the {@link java.util.Map.Entry#getKey() keys}.
* @param the generic type of the {@link java.util.Map.Entry#getValue() values}.
* @param the generic type of the value to {@link AbstractValidator#validate(Object) validate}.
* @param the generic type of the {@link #and() parent builder}.
* @param the generic type of this builder itself (this).
*
* @author hohwille
* @since 8.5.0
*/
public abstract class AbstractMapValidatorBuilder, PARENT, SELF extends AbstractMapValidatorBuilder>
extends ContainerValidatorBuilder {
private ObjectValidatorBuilder keySubBuilder;
private ObjectValidatorBuilder valueSubBuilder;
/**
* The constructor.
*
* @param parent the {@link #and() parent} builder.
*/
public AbstractMapValidatorBuilder(PARENT parent) {
super(parent);
}
/**
* @see ValidatorCollectionSize
*
* @param range the {@link Range} to limit the {@link Map#size() size} of the {@link Map}.
* @return this build instance for fluent API calls.
*/
public SELF size(Range range) {
return add(new ValidatorMapSize(range));
}
/**
* @see #size(Range)
*
* @param min the minimum {@link Map#size() size} allowed.
* @param max the maximum {@link Map#size() size} allowed.
* @return this build instance for fluent API calls.
*/
public SELF size(int min, int max) {
return size(RangeType.of(Integer.valueOf(min), Integer.valueOf(max)));
}
/**
* @see #size(Range)
*
* @param max the maximum {@link Map#size() size} allowed.
* @return this build instance for fluent API calls.
*/
public SELF max(int max) {
return size(0, max);
}
/**
* Creates a new {@link ObjectValidatorBuilder builder} for the {@link AbstractValidator validators} to invoke for
* each {@link Map#keySet() key} in the {@link Map}.
* Use {@link #and()} to return to this builder after the sub-builder is complete.
* A typical usage looks like this:
*
*
* [...].withKeys((f, v) -> f.create(v)).[...].and().[...].build()
*
*
* @param the generic type of the returned sub-builder.
* @param factory lambda function used to create the returned sub-builder by calling the according {@code create}
* method on the supplied {@link ObjectValidatorBuilderFactory} with the given dummy element.
* @return the new sub-builder.
*/
public > SUB withKeys(
BiFunction, K, SUB> factory) {
if (this.keySubBuilder != null) {
throw new IllegalStateException("keySubBuilder already exists!");
}
SUB sub = factory.apply(getSubFactory(), null);
this.keySubBuilder = sub;
return sub;
}
/**
* Creates a new {@link ObjectValidatorBuilder builder} for the {@link AbstractValidator validators} to invoke for
* each {@link Map#values() values} in the {@link Map}.
* Use {@link #and()} to return to this builder after the sub-builder is complete.
* A typical usage looks like this:
*
*
* [...].withValues((f, v) -> f.create(v)).[...].and().[...].build()
*
*
* @param the generic type of the returned sub-builder.
* @param factory lambda function used to create the returned sub-builder by calling the according {@code create}
* method on the supplied {@link ObjectValidatorBuilderFactory} with the given dummy element.
* @return the new sub-builder.
*/
public > SUB withValues(
BiFunction, V, SUB> factory) {
if (this.valueSubBuilder != null) {
throw new IllegalStateException("valueSubBuilder already exists!");
}
SUB sub = factory.apply(getSubFactory(), null);
this.valueSubBuilder = sub;
return sub;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public Validator super M> build() {
if (this.keySubBuilder != null) {
add(new ValidatorMapKeys(getValidators(this.keySubBuilder)));
}
if (this.valueSubBuilder != null) {
add(new ValidatorMapKeys(getValidators(this.valueSubBuilder)));
}
return super.build();
}
}