com.dimajix.shaded.everit.schema.loader.SchemaExtractor Maven / Gradle / Ivy
package com.dimajix.shaded.everit.schema.loader;
import static java.lang.String.format;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static java.util.Collections.singleton;
import static java.util.Collections.singletonList;
import static java.util.Objects.requireNonNull;
import static com.dimajix.shaded.everit.schema.loader.SpecificationVersion.DRAFT_4;
import static com.dimajix.shaded.everit.schema.loader.SpecificationVersion.DRAFT_7;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import com.dimajix.shaded.everit.schema.ArraySchema;
import com.dimajix.shaded.everit.schema.BooleanSchema;
import com.dimajix.shaded.everit.schema.CombinedSchema;
import com.dimajix.shaded.everit.schema.ConditionalSchema;
import com.dimajix.shaded.everit.schema.ConstSchema;
import com.dimajix.shaded.everit.schema.EnumSchema;
import com.dimajix.shaded.everit.schema.NotSchema;
import com.dimajix.shaded.everit.schema.NullSchema;
import com.dimajix.shaded.everit.schema.NumberSchema;
import com.dimajix.shaded.everit.schema.ObjectSchema;
import com.dimajix.shaded.everit.schema.Schema;
import com.dimajix.shaded.everit.schema.SchemaException;
import com.dimajix.shaded.everit.schema.StringSchema;
class KeyConsumer {
private final Set consumedKeys;
private final JsonObject schemaJson;
KeyConsumer(JsonObject schemaJson) {
this.schemaJson = schemaJson;
this.consumedKeys = new HashSet<>(schemaJson.keySet().size());
}
void keyConsumed(String key) {
if (schemaJson.keySet().contains(key)) {
consumedKeys.add(key);
}
}
JsonValue require(String key) {
keyConsumed(key);
return schemaJson.require(key);
}
Optional maybe(String key) {
keyConsumed(key);
return schemaJson.maybe(key);
}
public Set collect() {
return consumedKeys;
}
}
class ExtractionResult {
final Set consumedKeys;
final Collection> extractedSchemas;
ExtractionResult(Set consumedKeys, Collection> extractedSchemas) {
this.consumedKeys = requireNonNull(consumedKeys, "consumedKeys cannot be null");
this.extractedSchemas = requireNonNull(extractedSchemas, "extractedSchemas cannot be null");
}
ExtractionResult(String consumedKeys, Collection> extactedSchemas) {
this(singleton(consumedKeys), extactedSchemas);
}
}
interface SchemaExtractor {
ExtractionResult extract(JsonObject schemaJson);
}
abstract class AbstractSchemaExtractor implements SchemaExtractor {
static final List NUMBER_SCHEMA_PROPS = asList("minimum", "maximum",
"exclusiveMinimum", "exclusiveMaximum", "multipleOf");
static final List STRING_SCHEMA_PROPS = asList("minLength", "maxLength",
"pattern", "format");
protected JsonObject schemaJson;
private KeyConsumer consumedKeys;
final SchemaLoader defaultLoader;
private ExclusiveLimitHandler exclusiveLimitHandler;
AbstractSchemaExtractor(SchemaLoader defaultLoader) {
this.defaultLoader = requireNonNull(defaultLoader, "defaultLoader cannot be null");
}
@Override
public final ExtractionResult extract(JsonObject schemaJson) {
this.schemaJson = requireNonNull(schemaJson, "schemaJson cannot be null");
this.exclusiveLimitHandler = ExclusiveLimitHandler.ofSpecVersion(config().specVersion);
consumedKeys = new KeyConsumer(schemaJson);
return new ExtractionResult(consumedKeys.collect(), extract());
}
JsonValue require(String key) {
return consumedKeys.require(key);
}
Optional maybe(String key) {
return consumedKeys.maybe(key);
}
boolean containsKey(String key) {
return schemaJson.containsKey(key);
}
boolean schemaHasAnyOf(Collection propNames) {
return propNames.stream().anyMatch(schemaJson::containsKey);
}
LoaderConfig config() {
return schemaJson.ls.config;
}
ObjectSchema.Builder buildObjectSchema() {
config().specVersion.objectKeywords().forEach(consumedKeys::keyConsumed);
return new ObjectSchemaLoader(schemaJson.ls, config(), defaultLoader).load();
}
ArraySchema.Builder buildArraySchema() {
config().specVersion.arrayKeywords().forEach(consumedKeys::keyConsumed);
return new ArraySchemaLoader(schemaJson.ls, config(), defaultLoader).load();
}
NumberSchema.Builder buildNumberSchema() {
PropertySnifferSchemaExtractor.NUMBER_SCHEMA_PROPS.forEach(consumedKeys::keyConsumed);
NumberSchema.Builder builder = NumberSchema.builder();
maybe("minimum").map(JsonValue::requireNumber).ifPresent(builder::minimum);
maybe("maximum").map(JsonValue::requireNumber).ifPresent(builder::maximum);
maybe("multipleOf").map(JsonValue::requireNumber).ifPresent(builder::multipleOf);
maybe("exclusiveMinimum").ifPresent(exclMin -> exclusiveLimitHandler.handleExclusiveMinimum(exclMin, builder));
maybe("exclusiveMaximum").ifPresent(exclMax -> exclusiveLimitHandler.handleExclusiveMaximum(exclMax, builder));
return builder;
}
StringSchema.Builder buildStringSchema() {
PropertySnifferSchemaExtractor.STRING_SCHEMA_PROPS.forEach(consumedKeys::keyConsumed);
return new StringSchemaLoader(schemaJson.ls, config().formatValidators).load();
}
abstract List> extract();
}
class EnumSchemaExtractor extends AbstractSchemaExtractor {
EnumSchemaExtractor(SchemaLoader defaultLoader) {
super(defaultLoader);
}
@Override List> extract() {
if (!containsKey("enum")) {
return emptyList();
}
EnumSchema.Builder builder = EnumSchema.builder();
List
© 2015 - 2024 Weber Informatics LLC | Privacy Policy