
com.zuunr.json.schema.generation.BasicSchemaPerceptor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of json Show documentation
Show all versions of json Show documentation
Immutable JSON representation in Java
The newest version!
package com.zuunr.json.schema.generation;
import com.zuunr.json.*;
import com.zuunr.json.schema.Keywords;
import com.zuunr.json.schema.Schemas;
/**
* @author Niklas Eldberger
*/
public class BasicSchemaPerceptor implements SchemaPerceptor {
public final KeywordMapper keywordMapper;
public BasicSchemaPerceptor(KeywordMapper keywordMapper) {
this.keywordMapper = keywordMapper;
}
public BasicSchemaPerceptor() {
this(new KeywordMapper());
}
@Override
public JsonObject generateProperties(JsonValue rootValue, JsonArray path, JsonObject jsonObject, JsonObject pathsPerValue) {
return null;
}
@Override
public JsonObject generateStringSchema(JsonValue rootValue, JsonArray path, String stringValue, JsonObject pathsPerValue) {
KeywordMapperAndMatcher mapperAndMatcher = keywordMapper.chooseMapper(rootValue, path, JsonValue.of(stringValue), pathsPerValue);
JsonObjectBuilder builder = generateCommonKeywords(rootValue, path, JsonValue.of(stringValue), pathsPerValue, mapperAndMatcher, Schemas.STRING.builder());
int stringLength = stringValue.length();
applyKeyword(Keywords.MAX_LENGTH, JsonValue.of(stringLength), mapperAndMatcher, builder);
applyKeyword(Keywords.MIN_LENGTH, JsonValue.of(stringLength), mapperAndMatcher, builder);
// TODO: pattern
return KeywordMapper.applyRef(mapperAndMatcher, builder.build()); // applyRef must be last
}
public JsonObjectBuilder generateCommonKeywords(JsonValue rootValue, JsonArray path, JsonValue value, JsonObject pathsPerValue, KeywordMapperAndMatcher keywordMapperAndMatcher, JsonObjectBuilder schemaBuilder) {
applyKeyword(Keywords.CONST, value, keywordMapperAndMatcher, schemaBuilder);
return schemaBuilder;
}
@Override
public JsonObject generateNumericSchema(JsonValue rootValue, JsonArray path, JsonNumber numberValue, JsonObject pathsPerValue) {
JsonObjectBuilder builder;
KeywordMapperAndMatcher mapperAndMatcher = keywordMapper.chooseMapper(rootValue, path, numberValue.jsonValue(), pathsPerValue);
if (numberValue.isJsonInteger()) {
builder = generateCommonKeywords(rootValue, path, numberValue.jsonValue(), pathsPerValue, mapperAndMatcher, Schemas.INTEGER.builder());
} else {
builder = generateCommonKeywords(rootValue, path, numberValue.jsonValue(), pathsPerValue, mapperAndMatcher, Schemas.NUMBER.builder());
}
applyKeyword(Keywords.MAXIMUM, numberValue.jsonValue(), mapperAndMatcher, builder);
applyKeyword(Keywords.MINIMUM, numberValue.jsonValue(), mapperAndMatcher, builder);
return KeywordMapper.applyRef(mapperAndMatcher, builder.build());
}
@Override
public JsonObject generateObjectSchema(JsonValue rootValue, JsonArray path, JsonObject jsonObject, JsonObject pathsPerValue, KeywordMapperAndMatcher keywordMapperAndMatcher) {
KeywordMapperAndMatcher mapperAndMatcher = keywordMapper.chooseMapper(rootValue, path, jsonObject.jsonValue(), pathsPerValue);
JsonObjectBuilder builder = generateCommonKeywords(rootValue, path, jsonObject.jsonValue(), pathsPerValue, mapperAndMatcher, Schemas.OBJECT.builder());
applyKeyword(Keywords.REQUIRED, jsonObject.keys().sort().jsonValue(), mapperAndMatcher, builder);
JsonValue size = JsonValue.of(jsonObject.size());
applyKeyword(Keywords.MAX_PROPERTIES, size, mapperAndMatcher, builder);
applyKeyword(Keywords.MIN_PROPERTIES, size, mapperAndMatcher, builder);
return builder.build();
}
@Override
public JsonObject generateArraySchema(JsonValue rootValue, JsonArray path, JsonArray jsonArray, JsonObject pathsPerValue) {
KeywordMapperAndMatcher mapperAndMatcher = keywordMapper.chooseMapper(rootValue, path, jsonArray.jsonValue(), pathsPerValue);
JsonObjectBuilder schemaBuilder = generateCommonKeywords(rootValue, path, jsonArray.jsonValue(), pathsPerValue, mapperAndMatcher, Schemas.ARRAY.builder());
if (jsonArray.asSet().size() == jsonArray.size()) {
applyKeyword(Keywords.UNIQUE_ITEMS, JsonValue.TRUE, mapperAndMatcher, schemaBuilder);
}
JsonValue size = JsonValue.of(jsonArray.size());
applyKeyword(Keywords.MAX_ITEMS, size, mapperAndMatcher, schemaBuilder);
applyKeyword(Keywords.MIN_ITEMS, size, mapperAndMatcher, schemaBuilder);
return KeywordMapper.applyRef(mapperAndMatcher, schemaBuilder.build());
}
@Override
public JsonValue generateItemsSchema(JsonValue rootValue, JsonArray path, JsonArray jsonArrayInstance, JsonObject pathsPerValue) {
return null;
}
@Override
public JsonObject generateBooleanSchema(JsonValue rootValue, JsonArray path, Boolean value, JsonObject pathsPerValue) {
KeywordMapperAndMatcher mapperAndMatcher = keywordMapper.chooseMapper(rootValue, path, JsonValue.of(value), pathsPerValue);
return generateCommonKeywords(rootValue, path, JsonValue.of(value), pathsPerValue, mapperAndMatcher, Schemas.BOOLEAN.builder()).build();
}
private void applyKeyword(String keyword, JsonValue constraintFromExampleValue, KeywordMapperAndMatcher keywordMapperAndMatcher, JsonObjectBuilder schemaBuilder) {
JsonValue constraint = keywordMapperAndMatcher.keywordMapper.get("keywords", JsonObject.EMPTY).get(keyword);
if (constraint != null && !JsonValue.NULL.equals(constraint) && !JsonValue.FALSE.equals(constraint)) {
schemaBuilder.put(keyword, chooseConstraintValue(keyword, constraintFromExampleValue, constraint));
}
}
private JsonValue chooseConstraintValue(String keyword, JsonValue constraintFromExampleValue, JsonValue constraintFromMapper) {
if (!constraintFromMapper.isJsonArray()) {
return constraintFromExampleValue;
}
switch (keyword) {
case Keywords.MAX_LENGTH, Keywords.MAXIMUM, Keywords.MAX_ITEMS, Keywords.MAX_PROPERTIES: {
return firstConstraintGteExample(constraintFromExampleValue, constraintFromMapper.getJsonArray());
}
case Keywords.MIN_LENGTH, Keywords.MINIMUM, Keywords.MIN_ITEMS, Keywords.MIN_PROPERTIES: {
return firstConstraintLteExample(constraintFromExampleValue, constraintFromMapper.getJsonArray());
}
default:
}
return constraintFromExampleValue;
}
private JsonValue firstConstraintGteExample(JsonValue constraintFromExampleValue, JsonArray predefinedLimits) {
for (int i = 0; i < predefinedLimits.size(); i++) {
JsonValue limit = predefinedLimits.get(i);
if (limit.getJsonNumber().longValue() >= constraintFromExampleValue.getJsonNumber().longValue()) {
return limit;
}
}
return constraintFromExampleValue;
}
private JsonValue firstConstraintLteExample(JsonValue constraintFromExampleValue, JsonArray predefinedLimits) {
for (int i = 0; i < predefinedLimits.size(); i++) {
JsonValue limit = predefinedLimits.get(i);
if (limit.getJsonNumber().longValue() <= constraintFromExampleValue.getJsonNumber().longValue()) {
return limit;
}
}
return constraintFromExampleValue;
}
@Override
public JsonObject generateNullSchema(JsonValue rootValue, JsonArray path, JsonObject pathsPerValue) {
KeywordMapperAndMatcher mapperAndMatcher = keywordMapper.chooseMapper(rootValue, path, JsonValue.NULL, pathsPerValue);
JsonObjectBuilder builder = generateCommonKeywords(rootValue, path, JsonValue.NULL, pathsPerValue, mapperAndMatcher, Schemas.NULL.builder());
return builder.build();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy