1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package io.wcm.siteapi.openapi.validator;
21
22 import java.util.stream.Collectors;
23
24 import org.jetbrains.annotations.NotNull;
25 import org.openapi4j.core.util.TreeUtil;
26 import org.openapi4j.core.validation.ValidationResults.ValidationItem;
27 import org.openapi4j.schema.validator.ValidationData;
28 import org.openapi4j.schema.validator.v3.SchemaValidator;
29
30 import com.fasterxml.jackson.core.JsonProcessingException;
31 import com.fasterxml.jackson.databind.JsonNode;
32
33
34
35
36
37 public final class OpenApiSchemaValidator {
38
39 private final String suffix;
40 private final SchemaValidator schemaValidator;
41
42 OpenApiSchemaValidator(@NotNull String suffix, @NotNull SchemaValidator schemaValidator) {
43 this.suffix = suffix;
44 this.schemaValidator = schemaValidator;
45 }
46
47
48
49
50 public @NotNull String getSuffix() {
51 return this.suffix;
52 }
53
54
55
56
57
58
59 public void validate(@NotNull String jsonValue) throws ContentValidationException {
60 JsonNode node = readJson(jsonValue);
61 validateAgainstSchema(node);
62 }
63
64 private JsonNode readJson(@NotNull String jsonValue) throws ContentValidationException {
65 try {
66 return TreeUtil.json.readTree(jsonValue);
67 }
68 catch (JsonProcessingException ex) {
69 throw new ContentValidationException("Unable to parse JSON:\n" + jsonValue, ex);
70 }
71 }
72
73 private void validateAgainstSchema(@NotNull JsonNode node) throws ContentValidationException {
74 ValidationData<Void> validation = new ValidationData<>();
75 schemaValidator.validate(node, validation);
76 if (validation.isValid()) {
77 return;
78 }
79 String message = "JSON invalid for suffix '" + suffix + "': " + validation.results().items().stream()
80 .map(ValidationItem::toString)
81 .collect(Collectors.joining("\n"));
82 throw new ContentValidationException(message);
83 }
84
85 }