Skip to content

Commit 3989d6b

Browse files
Merge pull request #217 from JordonPhillips/minmax
Add validation for length trait values
2 parents 32c5a03 + 8a5fe05 commit 3989d6b

File tree

4 files changed

+135
-0
lines changed

4 files changed

+135
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package software.amazon.smithy.model.validation.validators;
17+
18+
import java.util.ArrayList;
19+
import java.util.List;
20+
import java.util.stream.Collectors;
21+
import software.amazon.smithy.model.Model;
22+
import software.amazon.smithy.model.shapes.Shape;
23+
import software.amazon.smithy.model.traits.LengthTrait;
24+
import software.amazon.smithy.model.traits.Trait;
25+
import software.amazon.smithy.model.validation.AbstractValidator;
26+
import software.amazon.smithy.model.validation.ValidationEvent;
27+
import software.amazon.smithy.utils.Pair;
28+
29+
public class LengthTraitValidator extends AbstractValidator {
30+
@Override
31+
public List<ValidationEvent> validate(Model model) {
32+
return model.shapes()
33+
.flatMap(shape -> Trait.flatMapStream(shape, LengthTrait.class))
34+
.flatMap(pair -> validateLengthTrait(model, pair.getLeft(), pair.getRight()).stream())
35+
.collect(Collectors.toList());
36+
}
37+
38+
private List<ValidationEvent> validateLengthTrait(Model model, Shape shape, LengthTrait trait) {
39+
List<ValidationEvent> events = new ArrayList<>();
40+
trait.getMin()
41+
.filter(min -> min < 0)
42+
.map(min -> error(shape, trait, "A length trait is applied with a negative `min` value."))
43+
.ifPresent(events::add);
44+
45+
trait.getMax()
46+
.filter(max -> max < 0)
47+
.map(max -> error(shape, trait, "A length trait is applied with a negative `max` value."))
48+
.ifPresent(events::add);
49+
50+
trait.getMin()
51+
.flatMap(min -> trait.getMax().map(max -> Pair.of(min, max)))
52+
.filter(pair -> pair.getLeft() > pair.getRight())
53+
.map(pair -> error(shape, trait, "A length trait is applied with a `min` value greater than "
54+
+ "its `max` value."))
55+
.map(events::add);
56+
return events;
57+
}
58+
}

smithy-model/src/main/resources/META-INF/services/software.amazon.smithy.model.validation.Validator

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ software.amazon.smithy.model.validation.validators.HttpPrefixHeadersTraitValidat
1515
software.amazon.smithy.model.validation.validators.HttpQueryTraitValidator
1616
software.amazon.smithy.model.validation.validators.HttpResponseCodeSemanticsValidator
1717
software.amazon.smithy.model.validation.validators.HttpUriConflictValidator
18+
software.amazon.smithy.model.validation.validators.LengthTraitValidator
1819
software.amazon.smithy.model.validation.validators.PaginatedTraitValidator
1920
software.amazon.smithy.model.validation.validators.PrivateAccessValidator
2021
software.amazon.smithy.model.validation.validators.RangeTraitValidator
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[ERROR] ns.foo#Invalid1: A length trait is applied with a negative `max` value. | LengthTrait
2+
[ERROR] ns.foo#Invalid2: A length trait is applied with a negative `min` value. | LengthTrait
3+
[ERROR] ns.foo#Invalid3: A length trait is applied with a `min` value greater than its `max` value. | LengthTrait
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
{
2+
"smithy": "0.4.0",
3+
"ns.foo": {
4+
"shapes": {
5+
"Valid1": {
6+
"type": "list",
7+
"member": {
8+
"target": "smithy.api#String"
9+
},
10+
"smithy.api#length": {
11+
"min": 0
12+
}
13+
},
14+
"Valid2": {
15+
"type": "list",
16+
"member": {
17+
"target": "smithy.api#String"
18+
},
19+
"smithy.api#length": {
20+
"max": 1
21+
}
22+
},
23+
"Valid3": {
24+
"type": "list",
25+
"member": {
26+
"target": "smithy.api#String"
27+
},
28+
"smithy.api#length": {
29+
"min": 0,
30+
"max": 1
31+
}
32+
},
33+
"Valid4": {
34+
"type": "list",
35+
"member": {
36+
"target": "smithy.api#String"
37+
},
38+
"smithy.api#length": {
39+
"min": 4,
40+
"max": 4
41+
}
42+
},
43+
"Invalid1": {
44+
"type": "list",
45+
"member": {
46+
"target": "smithy.api#String"
47+
},
48+
"smithy.api#length": {
49+
"max": -1
50+
}
51+
},
52+
"Invalid2": {
53+
"type": "list",
54+
"member": {
55+
"target": "smithy.api#String"
56+
},
57+
"smithy.api#length": {
58+
"min": -1
59+
}
60+
},
61+
"Invalid3": {
62+
"type": "list",
63+
"member": {
64+
"target": "smithy.api#String"
65+
},
66+
"smithy.api#length": {
67+
"min": 5,
68+
"max": 4
69+
}
70+
}
71+
}
72+
}
73+
}

0 commit comments

Comments
 (0)