Skip to content

Commit 707dd49

Browse files
authored
Add multiple validators to Parameters (#77073)
This PR implements support for multiple validators to a FieldMapper.Parameter. The Parameter#setValidator method was replaced by Parameter#addValidator that can be called multipled times to add validation to a parameter. All validators of a parameter will be executed in the same order as they have been added and if any of them fails all validation will failed.
1 parent ec11f9f commit 707dd49

File tree

16 files changed

+47
-36
lines changed

16 files changed

+47
-36
lines changed

modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/ScaledFloatFieldMapper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public static class Builder extends FieldMapper.Builder {
7070

7171
private final Parameter<Double> scalingFactor = new Parameter<>("scaling_factor", false, () -> null,
7272
(n, c, o) -> XContentMapValues.nodeDoubleValue(o), m -> toType(m).scalingFactor)
73-
.setValidator(v -> {
73+
.addValidator(v -> {
7474
if (v == null) {
7575
throw new IllegalArgumentException("Field [scaling_factor] is required");
7676
}

modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/SearchAsYouTypeFieldMapper.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ public static class Builder extends FieldMapper.Builder {
9797
// `doc_values=false`, even though it cannot be set; and so we need to continue
9898
// serializing it forever because of mapper assertions in mixed clusters.
9999
private final Parameter<Boolean> docValues = Parameter.docValuesParam(m -> false, false)
100-
.setValidator(v -> {
100+
.addValidator(v -> {
101101
if (v) {
102102
throw new MapperParsingException("Cannot set [doc_values] on field of type [search_as_you_type]");
103103
}
@@ -106,7 +106,7 @@ public static class Builder extends FieldMapper.Builder {
106106

107107
private final Parameter<Integer> maxShingleSize = Parameter.intParam("max_shingle_size", false,
108108
m -> builder(m).maxShingleSize.get(), Defaults.MAX_SHINGLE_SIZE)
109-
.setValidator(v -> {
109+
.addValidator(v -> {
110110
if (v < MAX_SHINGLE_SIZE_LOWER_BOUND || v > MAX_SHINGLE_SIZE_UPPER_BOUND) {
111111
throw new MapperParsingException("[max_shingle_size] must be at least [" + MAX_SHINGLE_SIZE_LOWER_BOUND
112112
+ "] and at most " + "[" + MAX_SHINGLE_SIZE_UPPER_BOUND + "], got [" + v + "]");

plugins/analysis-icu/src/main/java/org/elasticsearch/index/mapper/ICUCollationKeywordFieldMapper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ public static class Builder extends FieldMapper.Builder {
213213

214214
final Parameter<Integer> ignoreAbove
215215
= Parameter.intParam("ignore_above", true, m -> toType(m).ignoreAbove, Integer.MAX_VALUE)
216-
.setValidator(v -> {
216+
.addValidator(v -> {
217217
if (v < 0) {
218218
throw new IllegalArgumentException("[ignore_above] must be positive, got [" + v + "]");
219219
}

server/src/main/java/org/elasticsearch/index/mapper/CompletionFieldMapper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ public static class Builder extends FieldMapper.Builder {
133133
private final Parameter<Integer> maxInputLength = Parameter.intParam("max_input_length", true,
134134
m -> builder(m).maxInputLength.get(), Defaults.DEFAULT_MAX_INPUT_LENGTH)
135135
.addDeprecatedName("max_input_len")
136-
.setValidator(Builder::validateInputLength)
136+
.addValidator(Builder::validateInputLength)
137137
.alwaysSerialize();
138138
private final Parameter<Map<String, String>> meta = Parameter.metaParam();
139139

server/src/main/java/org/elasticsearch/index/mapper/CompositeRuntimeField.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public class CompositeRuntimeField implements RuntimeField {
3838
() -> null,
3939
RuntimeField::parseScript,
4040
RuntimeField.initializerNotSupported()
41-
).setValidator(s -> {
41+
).addValidator(s -> {
4242
if (s == null) {
4343
throw new IllegalArgumentException("composite runtime field [" + name + "] must declare a [script]");
4444
}
@@ -50,7 +50,7 @@ public class CompositeRuntimeField implements RuntimeField {
5050
Collections::emptyMap,
5151
(f, p, o) -> parseFields(f, o),
5252
RuntimeField.initializerNotSupported()
53-
).setValidator(objectMap -> {
53+
).addValidator(objectMap -> {
5454
if (objectMap == null || objectMap.isEmpty()) {
5555
throw new IllegalArgumentException("composite runtime field [" + name + "] must declare its [fields]");
5656
}

server/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,7 @@ public static final class Parameter<T> implements Supplier<T> {
588588
private final TriFunction<String, MappingParserContext, Object, T> parser;
589589
private final Function<FieldMapper, T> initializer;
590590
private boolean acceptsNull = false;
591-
private Consumer<T> validator = null;
591+
private List<Consumer<T>> validators = new ArrayList<>();
592592
private Serializer<T> serializer = XContentBuilder::field;
593593
private SerializerCheck<T> serializerCheck = (includeDefaults, isConfigured, value) -> includeDefaults || isConfigured;
594594
private Function<T, String> conflictSerializer = Objects::toString;
@@ -683,10 +683,11 @@ public Parameter<T> deprecated() {
683683
}
684684

685685
/**
686-
* Adds validation to a parameter, called after parsing and merging
686+
* Adds validation to a parameter, called after parsing and merging. Multiple
687+
* validators can be added and all of them will be executed.
687688
*/
688-
public Parameter<T> setValidator(Consumer<T> validator) {
689-
this.validator = validator;
689+
public Parameter<T> addValidator(Consumer<T> validator) {
690+
this.validators.add(validator);
690691
return this;
691692
}
692693

@@ -743,8 +744,9 @@ public Parameter<T> precludesParameters(Parameter<?>... ps) {
743744
}
744745

745746
void validate() {
746-
if (validator != null) {
747-
validator.accept(getValue());
747+
// Iterate over the list of validators and execute them one by one.
748+
for (Consumer<T> v : validators) {
749+
v.accept(getValue());
748750
}
749751
if (this.isConfigured()) {
750752
for (Parameter<?> p : requires) {
@@ -895,7 +897,7 @@ public static Parameter<String> restrictedStringParam(String name, boolean updat
895897
assert values.length > 0;
896898
Set<String> acceptedValues = new LinkedHashSet<>(Arrays.asList(values));
897899
return stringParam(name, updateable, initializer, values[0])
898-
.setValidator(v -> {
900+
.addValidator(v -> {
899901
if (acceptedValues.contains(v)) {
900902
return;
901903
}
@@ -1079,7 +1081,7 @@ protected void addScriptValidation(
10791081
Parameter<Boolean> indexParam,
10801082
Parameter<Boolean> docValuesParam
10811083
) {
1082-
scriptParam.setValidator(s -> {
1084+
scriptParam.addValidator(s -> {
10831085
if (s != null && indexParam.get() == false && docValuesParam.get() == false) {
10841086
throw new MapperParsingException("Cannot define script on field with index:false and doc_values:false");
10851087
}

server/src/main/java/org/elasticsearch/index/mapper/IpFieldMapper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public Builder(String name, ScriptCompiler scriptCompiler, boolean ignoreMalform
9090
this.script.precludesParameters(nullValue, ignoreMalformed);
9191
addScriptValidation(script, indexed, hasDocValues);
9292
this.dimension = Parameter.boolParam("dimension", false, m -> toType(m).dimension, false)
93-
.setValidator(v -> {
93+
.addValidator(v -> {
9494
if (v && (indexed.getValue() == false || hasDocValues.getValue() == false)) {
9595
throw new IllegalArgumentException(
9696
"Field [dimension] requires that [" + indexed.name + "] and [" + hasDocValues.name + "] are true"

server/src/main/java/org/elasticsearch/index/mapper/KeywordFieldMapper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ public Builder(String name, IndexAnalyzers indexAnalyzers, ScriptCompiler script
124124
this.script.precludesParameters(nullValue);
125125
addScriptValidation(script, indexed, hasDocValues);
126126

127-
this.dimension = Parameter.boolParam("dimension", false, m -> toType(m).dimension, false).setValidator(v -> {
127+
this.dimension = Parameter.boolParam("dimension", false, m -> toType(m).dimension, false).addValidator(v -> {
128128
if (v && (indexed.getValue() == false || hasDocValues.getValue() == false)) {
129129
throw new IllegalArgumentException(
130130
"Field [dimension] requires that [" + indexed.name + "] and [" + hasDocValues.name + "] are true"

server/src/main/java/org/elasticsearch/index/mapper/LegacyGeoShapeFieldMapper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ public Builder(String name, Version version, boolean ignoreMalformedByDefault, b
179179
this.ignoreMalformed = ignoreMalformedParam(m -> builder(m).ignoreMalformed.get(), ignoreMalformedByDefault);
180180
this.coerce = coerceParam(m -> builder(m).coerce.get(), coerceByDefault);
181181

182-
this.pointsOnly.setValidator(v -> {
182+
this.pointsOnly.addValidator(v -> {
183183
if (v == null) {
184184
return;
185185
}

server/src/main/java/org/elasticsearch/index/mapper/NumberFieldMapper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ public Builder(String name, NumberType type, ScriptCompiler compiler, boolean ig
115115
(n, c, o) -> o == null ? null : type.parse(o, false), m -> toType(m).nullValue).acceptsNull();
116116

117117
this.dimension = Parameter.boolParam("dimension", false, m -> toType(m).dimension, false)
118-
.setValidator(v -> {
118+
.addValidator(v -> {
119119
if (v && EnumSet.of(NumberType.INTEGER, NumberType.LONG, NumberType.BYTE, NumberType.SHORT).contains(type) == false) {
120120
throw new IllegalArgumentException("Parameter [dimension] cannot be set to numeric type [" + type.name + "]");
121121
}

0 commit comments

Comments
 (0)