• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

burningwave / json / #7

25 Oct 2023 06:36AM UTC coverage: 45.756% (-3.2%) from 48.947%
#7

push

Roberto-Gentili
Releasing new version

372 of 813 relevant lines covered (45.76%)

0.46 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

40.26
/src/main/java/org/burningwave/json/Validation.java
1
/*
2
 * This file is part of Burningwave JSON.
3
 *
4
 * Author: Roberto Gentili
5
 *
6
 * Hosted at: https://github.com/burningwave/json
7
 *
8
 * --
9
 *
10
 * The MIT License (MIT)
11
 *
12
 * Copyright (c) 2023 Roberto Gentili
13
 *
14
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
15
 * documentation files (the "Software"), to deal in the Software without restriction, including without
16
 * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
17
 * the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
18
 * conditions:
19
 *
20
 * The above copyright notice and this permission notice shall be included in all copies or substantial
21
 * portions of the Software.
22
 *
23
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
24
 * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
25
 * EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
27
 * OR OTHER DEALINGS IN THE SOFTWARE.
28
 */
29
package org.burningwave.json;
30

31
import java.util.ArrayList;
32
import java.util.Arrays;
33
import java.util.Collection;
34
import java.util.Map;
35
import java.util.function.Consumer;
36
import java.util.function.Function;
37
import java.util.function.Predicate;
38

39
import org.burningwave.Strings;
40
import org.burningwave.Throwables;
41

42
import com.fasterxml.jackson.module.jsonSchema.JsonSchema;
43
import com.fasterxml.jackson.module.jsonSchema.types.ArraySchema;
44
import com.fasterxml.jackson.module.jsonSchema.types.BooleanSchema;
45
import com.fasterxml.jackson.module.jsonSchema.types.IntegerSchema;
46
import com.fasterxml.jackson.module.jsonSchema.types.NumberSchema;
47
import com.fasterxml.jackson.module.jsonSchema.types.ObjectSchema;
48
import com.fasterxml.jackson.module.jsonSchema.types.StringSchema;
49

50
public interface Validation {
51

52
        public static class Config<I> {
53
                private static final Predicate<Path.Validation.Context<?, ?>> DEFAULT_PATH_FILTER;
54
                private static final Function<Check<?, ?, ?>, Predicate<Path.Validation.Context<?, ?>>> DEFAULT_CHECK_FILTER;
55

56
                static {
57
                        DEFAULT_PATH_FILTER =
1✔
58
                                pathValidationContext ->
59
                                        true;
1✔
60
                        DEFAULT_CHECK_FILTER = check ->
1✔
61
                                pathValidationContext ->
1✔
62
                                        true;
1✔
63
                }
1✔
64

65
                I jsonObjectOrSupplier;
66
                Predicate<Path.Validation.Context<?, ?>> pathFilter;
67
                Function<Check<?, ?, ?>, Predicate<Path.Validation.Context<?, ?>>> checkFilter;
68
                boolean validateAll;
69
                int logMode;
70
                Collection<String> checkGroupIds;
71

72
                private Config(I jsonObject) {
1✔
73
                        this.jsonObjectOrSupplier = jsonObject;
1✔
74
                        this.pathFilter = DEFAULT_PATH_FILTER;
1✔
75
                        this.checkFilter = DEFAULT_CHECK_FILTER;
1✔
76
                        this.logMode = 1;
1✔
77
                        this.checkGroupIds = new ArrayList<>();
1✔
78
                }
1✔
79

80
                public static <I> Config<I> forJsonObject(I jsonObject) {
81
                        return new Config<>(jsonObject);
1✔
82
                }
83

84
                public Config<I> withPathFilter(Predicate<Path.Validation.Context<?, ?>> pathFilter) {
85
                        this.pathFilter = pathFilter;
×
86
                        return this;
×
87
                }
88

89
                public Config<I> withCheckFilter(Function<Check<?, ?, ?>, Predicate<Path.Validation.Context<?, ?>>> checkFilter) {
90
                        this.checkFilter = checkFilter;
×
91
                        return this;
×
92
                }
93

94
                public Config<I> withCompleteValidation() {
95
                        this.validateAll = true;
1✔
96
                        return this;
1✔
97
                }
98

99
                public Config<I> withExitStrategyAtFirstError() {
100
                        this.validateAll = false;
×
101
                        return this;
×
102
                }
103

104
                public Config<I> withTheseChecks(String... checkGroupIds) {
105
                        this.checkGroupIds.addAll(Arrays.asList(checkGroupIds));
×
106
                        return this;
×
107
                }
108

109
                public Config<I> disableLogging() {
110
                        this.logMode = 0;
×
111
                        return this;
×
112
                }
113

114
                public Config<I> enableDeepLogging() {
115
                        this.logMode = 2;
×
116
                        return this;
×
117
                }
118

119
                boolean isDeepLoggingEnabled() {
120
                        return logMode == 2;
1✔
121
                }
122

123
                boolean isErrorLoggingEnabled() {
124
                        return isDeepLoggingEnabled() || logMode == 1;
×
125
                }
126

127
                Collection<String> getGroupIds() {
128
                        return checkGroupIds;
1✔
129
                }
130
        }
131

132
        public static class Context {
133
                static final String MOCK_SCHEMA_LABEL;
134
                protected static final Object logger;
135

136
                static {
137
                        logger = SLF4J.INSTANCE.tryToInitLogger(Context.class);
1✔
138
                        MOCK_SCHEMA_LABEL = Strings.INSTANCE.toStringWithRandomUUIDSuffix("schemaMock");
1✔
139
                }
1✔
140

141
                final Function<Path.Validation.Context<?, ?>, Function<String, Function<String, Function<Object[], Throwable>>>> exceptionBuilder;
142
                final Validation.Config<?> validationConfig;
143
                final ObjectHandler inputHandler;
144
                final Collection<Throwable> exceptions;
145
                final Function<Path.Validation.Context<?, ?>, Consumer<Throwable>> exceptionAdder;
146
                final Collection<ObjectCheck> objectChecks;
147
                final Collection<IndexedObjectCheck<?>> indexedObjectChecks;
148
                final Collection<LeafCheck<?, ?>> leafChecks;
149

150
                Context(
151
                                Function<Path.Validation.Context<?, ?>, Function<String, Function<String, Function<Object[], Throwable>>>> exceptionBuilder,
152
                        Validation.Config<?> validationConfig,
153
                        ObjectHandler jsonObjectWrapper,
154
                        Collection<ObjectCheck> objectChecks,
155
                        Collection<IndexedObjectCheck<?>> indexedObjectChecks,
156
                        Collection<LeafCheck<?, ?>> leafChecks
157
                ) {
1✔
158
                        this.exceptionBuilder = exceptionBuilder;
1✔
159
                        this.validationConfig = validationConfig;
1✔
160
                        this.inputHandler = jsonObjectWrapper;
1✔
161
                        this.exceptions = validationConfig.validateAll ? new ArrayList<>() : null;
1✔
162
                        this.exceptionAdder = validationConfig.validateAll ?
1✔
163
                                pathValidationContext -> exceptions::add :
×
164
                                pathValidationContext -> exc -> {
×
165
                                        if (logger != null && validationConfig.isErrorLoggingEnabled()) {
×
166
                                                ((org.slf4j.Logger)logger).debug(
×
167
                                                        "Validation of path {} failed",
168
                                                        pathValidationContext.path
169
                                                );
170
                                        }
171
                                        Throwables.INSTANCE.throwException(exc);
×
172
                                };
×
173
                        this.objectChecks = objectChecks;
1✔
174
                        this.indexedObjectChecks = indexedObjectChecks;
1✔
175
                        this.leafChecks = leafChecks;
1✔
176
                }
1✔
177

178
                void rejectValue(
179
                        Path.Validation.Context<?, ?> pathValidationContext,
180
                        String checkType,
181
                        String message,
182
                        Object... messageArgs
183
                ) {
184
                        exceptionAdder.apply(
×
185
                                pathValidationContext
186
                        ).accept(
×
187
                                exceptionBuilder
188
                                .apply(pathValidationContext)
×
189
                                .apply(checkType)
×
190
                                .apply(message)
×
191
                                .apply(messageArgs)
×
192
                        );
193
                }
×
194

195
                boolean checkValue(JsonSchema jsonSchema, Object value) {
196
                        if (value != null) {
×
197
                                if (!checkUnindexedObject(jsonSchema, value)) {
×
198
                                        return false;
×
199
                                } else if (jsonSchema instanceof ArraySchema) {
×
200
                                        if (!(value instanceof Collection)) {
×
201
                                                return false;
×
202
                                        }
203
                                        JsonSchema itemsSchema = ((ArraySchema)jsonSchema).getItems().asSingleItems().getSchema();
×
204
                                        for (Object item : (Collection<?>)value) {
×
205
                                                if (!checkUnindexedObject(itemsSchema, item)) {
×
206
                                                        return false;
×
207
                                                }
208
                                        }
×
209
                                }
210
                        }
211
                        return true;
×
212
                }
213

214
                private boolean checkUnindexedObject(JsonSchema jsonSchema, Object value) {
215
                        return (jsonSchema instanceof ObjectSchema && value instanceof Map) ||
×
216
                                (jsonSchema instanceof StringSchema && value instanceof String) ||
217
                                (jsonSchema instanceof IntegerSchema && value instanceof Integer) ||
218
                                 (jsonSchema instanceof NumberSchema && value instanceof Number) ||
219
                                 (jsonSchema instanceof BooleanSchema && value instanceof Boolean);
220
                }
221

222
                public ObjectHandler getInputHandler() {
223
                        return inputHandler;
×
224
                }
225

226
        }
227

228
        public static class Exception extends RuntimeException {
229
                private static final long serialVersionUID = 391707186751457489L;
230

231
                protected final String path;
232
                protected final String checkType;
233

234
                public Exception(String path, String checkType, String message) {
235
                        super(path + ": " + message);
×
236
                        this.path = path;
×
237
                        this.checkType = checkType;
×
238
                }
×
239

240
                public String getPath() {
241
                        return path;
×
242
                }
243

244
                public String getCheckType() {
245
                        return this.checkType;
×
246
                }
247

248
        }
249

250
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc