Package com.bazaarvoice.commons.data.model.json.schema.types

Source Code of com.bazaarvoice.commons.data.model.json.schema.types.JSONSchemaArrayType

package com.bazaarvoice.commons.data.model.json.schema.types;

import com.bazaarvoice.commons.data.model.json.GenericJSONArrayList;
import com.bazaarvoice.commons.data.model.json.schema.JSONSchema;
import com.bazaarvoice.commons.data.model.json.schema.JSONSchemaType;
import com.bazaarvoice.commons.data.model.json.schema.JSONSchemas;
import com.bazaarvoice.commons.data.model.json.schema.validation.ResultType;
import com.bazaarvoice.commons.data.model.json.schema.validation.ValidationResult;
import com.bazaarvoice.commons.data.model.json.schema.validation.ValidationResults;
import com.google.common.collect.Collections2;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import org.json.JSONArray;

import javax.annotation.Nullable;
import java.util.AbstractCollection;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

public class JSONSchemaArrayType implements JSONSchemaType<JSONSchemaArrayType> {
    private List<JSONSchema> _items = Collections.emptyList();
    private JSONSchema _additionalItemsSchema;

    /**
     * Determines whether or not this array is a tuple.
     */
    public boolean isTuple() {
        return _items.size() > 1;
    }

    public List<JSONSchema> getItems() {
        return _items;
    }

    public void setItems(Iterable<JSONSchema> items) {
        _items = Lists.newArrayList(items);
    }

    public JSONSchemaArrayType items(Iterable<JSONSchema> items) {
        setItems(items);
        return this;
    }

    public JSONSchemaArrayType items(JSONSchema... items) {
        setItems(Arrays.asList(items));
        return this;
    }

    /**
     * Assumes the array isn't a tuple and returns the schema for the items allowed in this array.
     */
    public JSONSchema getItem() {
        if (_items.isEmpty()) {
            return new JSONSchema();
        }

        return _items.get(0);
    }

    public void setItem(JSONSchema item) {
        _items = Collections.singletonList(item);
    }

    public JSONSchemaArrayType item(JSONSchema item) {
        setItem(item);
        return this;
    }

    public JSONSchema getAdditionalItemsSchema() {
        return _additionalItemsSchema;
    }

    public void setAdditionalItemsSchema(JSONSchema additionalItemsSchema) {
        _additionalItemsSchema = additionalItemsSchema;
    }

    /**
     * When a tuple, sets the schema for any additional items. If null, additional items are not allowed. Defaults to ANY.
     */
    public JSONSchemaArrayType additionalItemsSchema(JSONSchema additionalItemsSchema) {
        setAdditionalItemsSchema(additionalItemsSchema);
        return this;
    }

    public JSONSchemaArrayType allowAdditionalItems() {
        setAdditionalItemsSchema(new JSONSchema());
        return this;
    }

    public JSONSchemaArrayType disallowAdditionalItems() {
        setAdditionalItemsSchema(null);
        return this;
    }

    @Override
    public JSONSchemaArrayType clone() {
        return new JSONSchemaArrayType().items(Iterables.transform(_items, JSONSchemas.CloningFunction.INSTANCE)).
                additionalItemsSchema(_additionalItemsSchema != null ? _additionalItemsSchema.clone() : null);
    }

    @Override
    public JSONSchemaArrayType merge(@Nullable JSONSchemaArrayType parentType) {
        if (parentType == null) {
            return this;
        }

        int size = _items.size();
        if (size == parentType._items.size()) {
            // only merge the parent type's items if both are not a tuple or the tuples are the same arity
            for (int index = 0; index < size; index++) {
                _items.get(index).merge(parentType._items.get(index));
            }
        } else if (size == 0) {
            setItems(Collections2.transform(parentType._items, JSONSchemas.CloningFunction.INSTANCE));
        }

        if (_additionalItemsSchema != null) {
            if (_additionalItemsSchema.isEmpty() && parentType._additionalItemsSchema == null) {
                // null value means disallow additional items, so parent null convey when this is the "empty" schema
                _additionalItemsSchema = null;
            } else {
                _additionalItemsSchema.merge(parentType._additionalItemsSchema);
            }
        }

        return this;
    }

    @Override
    public void validate(JSONSchema schema, Object obj, String path, ValidationResults results) {
        Collection coll;
        if (obj instanceof JSONArray) {
            coll = new GenericJSONArrayList((JSONArray) obj);
        } else if (obj instanceof Collection) {
            coll = (Collection) obj;
        } else {
            final Iterable iter = (Iterable) obj;
            coll = new AbstractCollection() {
                @Override
                public Iterator iterator() {
                    return iter.iterator();
                }

                @Override
                public int size() {
                    return Iterables.size(iter);
                }
            };
        }

        if (isTuple()) {
            int tupleSize = _items.size();
            int collSize = _items.size();
            if (tupleSize > collSize) {
                results.addResult(new ValidationResult().type(ResultType.CONSTRAINT_VIOLATION).path(path).message("Tuple is not the correct size " + tupleSize + ": " + coll));
            }

            Iterator<JSONSchema> tupleIter = _items.iterator();
            Iterator collIter = coll.iterator();
            int index = 0;
            while (tupleIter.hasNext() && collIter.hasNext()) {
                JSONSchema tupleSchema = tupleIter.next();
                Object tupleObj = collIter.next();
                tupleSchema.validate(tupleObj, path + "[" + index + "]", results);

                index++;
            }

            if (_additionalItemsSchema != null) {
                while (collIter.hasNext()) {
                    Object additionalObj = collIter.next();
                    _additionalItemsSchema.validate(additionalObj, path + "[" + index + "]", results);

                    index++;
                }
            } else if (collIter.hasNext()) {
                results.addResult(new ValidationResult().type(ResultType.CONSTRAINT_VIOLATION).path(path).message("Tuple does not allow additional items:" + coll));
            }
        } else {
            int index = 0;
            JSONSchema itemSchema = getItem();
            for (final Object collObj : coll) {
                itemSchema.validate(collObj, path + "[" + index + "]", results);

                index++;
            }
        }
    }

    @Override
    public String toString() {
        return super.toString() +
                "[isTuple=" + isTuple() + "]" +
                "[items=" + _items + "]" +
                "[additionalItemsSchema=" + _additionalItemsSchema + "]";
    }
}
TOP

Related Classes of com.bazaarvoice.commons.data.model.json.schema.types.JSONSchemaArrayType

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.