All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fibanez.jsonschema.content.generator.schemaMerger.NumberSchemaMerger Maven / Gradle / Ivy

package com.fibanez.jsonschema.content.generator.schemaMerger;

import com.fibanez.jsonschema.content.generator.exception.GeneratorException;
import org.everit.json.schema.NumberSchema;
import org.everit.json.schema.Schema;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import static com.fibanez.jsonschema.content.Context.UNPROCESSED_NOT_MULTIPLE_OF;

final class NumberSchemaMerger implements SchemaMerger {

    private final NumberSchema.Builder schemaBuilder;

    NumberSchemaMerger() {
        this.schemaBuilder = new NumberSchema.Builder();
    }

    @Override
    public SchemaMerger combine(Schema schema) {
        if (schema instanceof NumberSchema) {
            doCombine((NumberSchema) schema);
        } else {
            throw new GeneratorException("Unsupported merge schema '%s'", schema.getClass());
        }
        return this;
    }

    @Override
    public NumberSchemaMerger not(Schema schema) {
        if (schema instanceof NumberSchema) {
            doNot((NumberSchema) schema);
        } else {
            throw new GeneratorException("Unsupported negate schema '%s'", schema.getClass());
        }
        return this;
    }

    @Override
    public NumberSchema getSchema() {
        return schemaBuilder.build();
    }

    private void doCombine(NumberSchema schema) {
        if (schema.getMinimum() != null) {
            schemaBuilder.minimum(schema.getMinimum());
        }
        if (schema.getMaximum() != null) {
            schemaBuilder.maximum(schema.getMaximum());
        }
        if (schema.getMultipleOf() != null) {
            schemaBuilder.multipleOf(schema.getMultipleOf());
        }
        if (schema.getExclusiveMinimumLimit() != null) {
            schemaBuilder.exclusiveMinimum(schema.getExclusiveMinimumLimit());
        }
        if (schema.getExclusiveMaximumLimit() != null) {
            schemaBuilder.exclusiveMaximum(schema.getExclusiveMaximumLimit());
        }
        Map unprocessedProperties = schema.getUnprocessedProperties();
        if (unprocessedProperties != null && !unprocessedProperties.isEmpty()) {
            schemaBuilder.unprocessedProperties(unprocessedProperties);
        }

        schemaBuilder.exclusiveMinimum(schema.isExclusiveMinimum());
        schemaBuilder.exclusiveMaximum(schema.isExclusiveMaximum());
        schemaBuilder.requiresNumber(schema.isRequiresNumber());
        schemaBuilder.requiresInteger(schema.requiresInteger());
        schemaBuilder.unprocessedProperties(schema.getUnprocessedProperties());
    }

    private void doNot(NumberSchema toNegateSchema) {
        NumberSchema current = getSchema();

        Number minimum = getMinNumber(current.getMinimum(), current.getMaximum(), toNegateSchema.getMaximum());
        Number maximum = getMaxNumber(minimum, current.getMaximum(), toNegateSchema.getMinimum());

        schemaBuilder.minimum(minimum);
        schemaBuilder.maximum(maximum);

        if (toNegateSchema.getMultipleOf() != null) {
            // Copy all unprocessed Props
            Map copyUnprocessed = new HashMap<>(current.getUnprocessedProperties());
            appendNotMultipleOf(copyUnprocessed, toNegateSchema);
            schemaBuilder.unprocessedProperties(copyUnprocessed);
        }

    }

    private Number getMinNumber(Number minimum, Number maximum, Number minNegated) {
        if (minNegated == null) {
            return minimum;
        }
        if (maximum != null && compare(minNegated, maximum) > 0) {
            return minimum;
        }
        return minNegated;
    }

    private Number getMaxNumber(Number minimum, Number maximum, Number maxNegated) {
        if (maxNegated == null) {
            return maximum;
        }
        if (minimum != null && compare(minimum, maxNegated) > 0) {
            return maximum;
        }
        return maxNegated;
    }

    @SuppressWarnings("unchecked")
    private void appendNotMultipleOf(Map unprocessed, NumberSchema schema) {
        unprocessed.putIfAbsent(UNPROCESSED_NOT_MULTIPLE_OF, new HashSet<>());
        Set notMultipleOfs = ((Set) unprocessed.get(UNPROCESSED_NOT_MULTIPLE_OF));
        notMultipleOfs.add(schema.getMultipleOf());
    }

    private int compare(Number a, Number b) {
        if (a instanceof Double) {
            return Double.compare(a.doubleValue(), b.doubleValue());
        } else if (a instanceof Float) {
            return Float.compare(a.floatValue(), b.floatValue());
        } else if (a instanceof Long) {
            return Long.compare(a.longValue(), b.longValue());
        } else {
            return Integer.compare(a.intValue(), b.intValue());
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy