-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
30 changed files
with
2,740 additions
and
0 deletions.
There are no files selected for viewing
51 changes: 51 additions & 0 deletions
51
fusion-json/src/main/java/io/yupiik/fusion/json/schema/validation/JsonSchemaValidator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/* | ||
* Copyright (c) 2022 - present - Yupiik SAS - https://www.yupiik.com | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
package io.yupiik.fusion.json.schema.validation; | ||
|
||
import java.util.function.Function; | ||
import java.util.stream.Stream; | ||
|
||
import static java.util.Collections.emptyList; | ||
import static java.util.stream.Collectors.toList; | ||
|
||
public class JsonSchemaValidator implements Function<Object, ValidationResult>, AutoCloseable { | ||
private static final ValidationResult SUCCESS = new ValidationResult(emptyList()); | ||
|
||
private final Function<Object, Stream<ValidationResult.ValidationError>> validationFunction; | ||
|
||
JsonSchemaValidator(final Function<Object, Stream<ValidationResult.ValidationError>> validationFunction) { | ||
this.validationFunction = validationFunction; | ||
} | ||
|
||
@Override | ||
public ValidationResult apply(final Object object) { | ||
final var errors = validationFunction.apply(object).collect(toList()); | ||
if (!errors.isEmpty()) { | ||
return new ValidationResult(errors); | ||
} | ||
return SUCCESS; | ||
} | ||
|
||
@Override | ||
public void close() { | ||
// no-op | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "JsonSchemaValidator{validationFunction=" + validationFunction + '}'; | ||
} | ||
} |
301 changes: 301 additions & 0 deletions
301
...son/src/main/java/io/yupiik/fusion/json/schema/validation/JsonSchemaValidatorFactory.java
Large diffs are not rendered by default.
Oops, something went wrong.
27 changes: 27 additions & 0 deletions
27
fusion-json/src/main/java/io/yupiik/fusion/json/schema/validation/ValidationResult.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/* | ||
* Copyright (c) 2022 - present - Yupiik SAS - https://www.yupiik.com | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
package io.yupiik.fusion.json.schema.validation; | ||
|
||
import java.util.List; | ||
|
||
public record ValidationResult(List<ValidationError> errors) { | ||
public boolean isSuccess() { | ||
return errors.isEmpty(); | ||
} | ||
|
||
public record ValidationError(String field, String message) { | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
fusion-json/src/main/java/io/yupiik/fusion/json/schema/validation/spi/ValidationContext.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
* Copyright (c) 2022 - present - Yupiik SAS - https://www.yupiik.com | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
package io.yupiik.fusion.json.schema.validation.spi; | ||
|
||
import java.util.Map; | ||
import java.util.function.Function; | ||
import java.util.stream.Stream; | ||
|
||
import static java.util.stream.Collectors.joining; | ||
|
||
public record ValidationContext(String[] path, Map<String, Object> schema, Function<Object, Object> valueProvider) { | ||
public String toPointer() { | ||
return Stream.of(path).collect(joining("/", "/", "")); | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
...n-json/src/main/java/io/yupiik/fusion/json/schema/validation/spi/ValidationExtension.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/* | ||
* Copyright (c) 2022 - present - Yupiik SAS - https://www.yupiik.com | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
package io.yupiik.fusion.json.schema.validation.spi; | ||
|
||
import io.yupiik.fusion.json.schema.validation.ValidationResult; | ||
|
||
import java.util.Optional; | ||
import java.util.function.Function; | ||
import java.util.stream.Stream; | ||
|
||
public interface ValidationExtension { | ||
Optional<Function<Object, Stream<ValidationResult.ValidationError>>> create(ValidationContext model); | ||
} |
44 changes: 44 additions & 0 deletions
44
...c/main/java/io/yupiik/fusion/json/schema/validation/spi/builtin/BaseNumberValidation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* | ||
* Copyright (c) 2022 - present - Yupiik SAS - https://www.yupiik.com | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
package io.yupiik.fusion.json.schema.validation.spi.builtin; | ||
|
||
import io.yupiik.fusion.json.schema.validation.ValidationResult; | ||
import io.yupiik.fusion.json.schema.validation.spi.builtin.type.TypeFilter; | ||
|
||
import java.util.function.Function; | ||
import java.util.stream.Stream; | ||
|
||
abstract class BaseNumberValidation extends BaseValidation { | ||
protected final double bound; | ||
|
||
BaseNumberValidation(final String pointer, final Function<Object, Object> extractor, final double bound) { | ||
super(pointer, extractor, TypeFilter.NUMBER); | ||
this.bound = bound; | ||
} | ||
|
||
@Override | ||
protected Stream<ValidationResult.ValidationError> onNumber(final Number number) { | ||
final double val = number.doubleValue(); | ||
if (isValid(val)) { | ||
return Stream.empty(); | ||
} | ||
return toError(val); | ||
} | ||
|
||
protected abstract boolean isValid(double val); | ||
|
||
protected abstract Stream<ValidationResult.ValidationError> toError(double val); | ||
} |
91 changes: 91 additions & 0 deletions
91
...son/src/main/java/io/yupiik/fusion/json/schema/validation/spi/builtin/BaseValidation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
/* | ||
* Copyright (c) 2022 - present - Yupiik SAS - https://www.yupiik.com | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
package io.yupiik.fusion.json.schema.validation.spi.builtin; | ||
|
||
import io.yupiik.fusion.json.schema.validation.ValidationResult; | ||
import io.yupiik.fusion.json.schema.validation.spi.builtin.type.TypeFilter; | ||
|
||
import java.util.Collection; | ||
import java.util.Map; | ||
import java.util.function.Function; | ||
import java.util.stream.Stream; | ||
|
||
public abstract class BaseValidation implements Function<Object, Stream<ValidationResult.ValidationError>> { | ||
protected final String pointer; | ||
protected final Function<Object, Object> extractor; | ||
private final TypeFilter typeValidator; | ||
private final boolean rootCanBeNull; | ||
|
||
public BaseValidation(final String pointer, final Function<Object, Object> extractor, final TypeFilter typeValidator) { | ||
this.pointer = pointer; | ||
this.extractor = extractor != null ? extractor : v -> v; | ||
this.rootCanBeNull = extractor != null; | ||
this.typeValidator = typeValidator; | ||
} | ||
|
||
@Override | ||
@SuppressWarnings("unchecked") | ||
public Stream<ValidationResult.ValidationError> apply(final Object obj) { | ||
if (obj == null && rootCanBeNull) { | ||
return Stream.empty(); | ||
} | ||
|
||
final var value = extractor.apply(obj); | ||
if (!typeValidator.test(value)) { | ||
return Stream.empty(); | ||
} | ||
|
||
if (value instanceof String s) { | ||
return onString(s); | ||
} | ||
if (value instanceof Number n) { | ||
return onNumber(n); | ||
} | ||
if (value instanceof Boolean b) { | ||
return onBoolean(b); | ||
} | ||
if (value instanceof Collection<?> c) { | ||
return onArray(c); | ||
} | ||
if (value instanceof Map<?, ?> m) { | ||
return onObject((Map<String, Object>) m); | ||
} | ||
if (value == null) { | ||
return Stream.empty(); | ||
} | ||
throw new IllegalArgumentException("Unsupported value type: " + value); | ||
} | ||
|
||
protected Stream<ValidationResult.ValidationError> onArray(final Collection<?> array) { | ||
return Stream.empty(); | ||
} | ||
|
||
protected Stream<ValidationResult.ValidationError> onObject(final Map<String, Object> object) { | ||
return Stream.empty(); | ||
} | ||
|
||
protected Stream<ValidationResult.ValidationError> onNumber(final Number number) { | ||
return Stream.empty(); | ||
} | ||
|
||
protected Stream<ValidationResult.ValidationError> onBoolean(final boolean value) { | ||
return Stream.empty(); | ||
} | ||
|
||
protected Stream<ValidationResult.ValidationError> onString(final String string) { | ||
return Stream.empty(); | ||
} | ||
} |
72 changes: 72 additions & 0 deletions
72
...src/main/java/io/yupiik/fusion/json/schema/validation/spi/builtin/ContainsValidation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/* | ||
* Copyright (c) 2022 - present - Yupiik SAS - https://www.yupiik.com | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
package io.yupiik.fusion.json.schema.validation.spi.builtin; | ||
|
||
import io.yupiik.fusion.json.schema.validation.JsonSchemaValidator; | ||
import io.yupiik.fusion.json.schema.validation.JsonSchemaValidatorFactory; | ||
import io.yupiik.fusion.json.schema.validation.ValidationResult; | ||
import io.yupiik.fusion.json.schema.validation.spi.builtin.type.TypeFilter; | ||
import io.yupiik.fusion.json.schema.validation.spi.ValidationContext; | ||
import io.yupiik.fusion.json.schema.validation.spi.ValidationExtension; | ||
|
||
import java.util.Collection; | ||
import java.util.Map; | ||
import java.util.Optional; | ||
import java.util.function.Function; | ||
import java.util.stream.Stream; | ||
|
||
public class ContainsValidation implements ValidationExtension { | ||
private final JsonSchemaValidatorFactory factory; | ||
|
||
public ContainsValidation(final JsonSchemaValidatorFactory factory) { | ||
this.factory = factory; | ||
} | ||
|
||
@Override | ||
@SuppressWarnings("unchecked") | ||
public Optional<Function<Object, Stream<ValidationResult.ValidationError>>> create(final ValidationContext model) { | ||
return Optional.ofNullable(model.schema().get("contains")) | ||
.filter(TypeFilter.OBJECT) | ||
.map(it -> new ItemsValidator(model.toPointer(), model.valueProvider(), factory.newInstance((Map<String, Object>) it))); | ||
} | ||
|
||
private static class ItemsValidator extends BaseValidation { | ||
private final JsonSchemaValidator validator; | ||
|
||
private ItemsValidator(final String pointer, | ||
final Function<Object, Object> extractor, | ||
JsonSchemaValidator validator) { | ||
super(pointer, extractor, TypeFilter.ARRAY); | ||
this.validator = validator; | ||
} | ||
|
||
@Override | ||
protected Stream<ValidationResult.ValidationError> onArray(final Collection<?> array) { | ||
for (final var value : array) { | ||
final var itemErrors = validator.apply(value).errors(); | ||
if (itemErrors.isEmpty()) { | ||
return Stream.empty(); | ||
} | ||
} | ||
return Stream.of(new ValidationResult.ValidationError(pointer, "No item matching the expected schema")); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "Contains{validator=" + validator + ", pointer='" + pointer + "'}"; | ||
} | ||
} | ||
} |
Oops, something went wrong.