com.alibaba.fastjson2.schema.ArraySchema Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fastjson2 Show documentation
Show all versions of fastjson2 Show documentation
Fastjson is a JSON processor (JSON parser + JSON generator) written in Java
package com.alibaba.fastjson2.schema;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONException;
import com.alibaba.fastjson2.JSONObject;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.IntFunction;
import java.util.function.Predicate;
public final class ArraySchema
extends JSONSchema {
final Map definitions;
final Map defs;
final boolean typed;
final int maxLength;
final int minLength;
JSONSchema itemSchema;
final JSONSchema[] prefixItems;
final boolean additionalItems;
final JSONSchema additionalItem;
final JSONSchema contains;
final int minContains;
final int maxContains;
final boolean uniqueItems;
final AllOf allOf;
final AnyOf anyOf;
final OneOf oneOf;
final boolean encoded;
public ArraySchema(JSONObject input, JSONSchema root) {
super(input);
this.typed = "array".equals(input.get("type"));
this.definitions = new LinkedHashMap<>();
this.defs = new LinkedHashMap<>();
this.encoded = input.getBooleanValue("encoded", false);
JSONObject definitions = input.getJSONObject("definitions");
if (definitions != null) {
for (Map.Entry entry : definitions.entrySet()) {
String entryKey = entry.getKey();
JSONObject entryValue = (JSONObject) entry.getValue();
JSONSchema schema = JSONSchema.of(entryValue, root == null ? this : root);
this.definitions.put(entryKey, schema);
}
}
JSONObject defs = input.getJSONObject("$defs");
if (defs != null) {
for (Map.Entry entry : defs.entrySet()) {
String entryKey = entry.getKey();
JSONObject entryValue = (JSONObject) entry.getValue();
JSONSchema schema = JSONSchema.of(entryValue, root == null ? this : root);
this.defs.put(entryKey, schema);
}
}
this.minLength = input.getIntValue("minItems", -1);
this.maxLength = input.getIntValue("maxItems", -1);
Object items = input.get("items");
Object additionalItems = input.get("additionalItems");
JSONArray prefixItems = input.getJSONArray("prefixItems");
boolean additionalItemsSupport;
if (items == null) {
additionalItemsSupport = true;
this.itemSchema = null;
} else if (items instanceof Boolean) {
additionalItemsSupport = (Boolean) items;
this.itemSchema = null;
} else if (items instanceof JSONArray) {
if (prefixItems == null) {
prefixItems = (JSONArray) items;
} else {
throw new JSONException("schema error, items : " + items);
}
this.itemSchema = null;
additionalItemsSupport = true;
} else {
additionalItemsSupport = true;
this.itemSchema = JSONSchema.of((JSONObject) items, root != null ? root : this);
}
if (additionalItems instanceof JSONObject) {
additionalItem = JSONSchema.of((JSONObject) additionalItems, root == null ? this : root);
additionalItemsSupport = true;
} else if (additionalItems instanceof Boolean) {
additionalItemsSupport = (Boolean) additionalItems;
this.additionalItem = null;
} else {
this.additionalItem = null;
}
// ((itemSchema != null && !(itemSchema instanceof Any))
// || this.prefixItems.length > 0)
if (itemSchema != null && !(itemSchema instanceof Any)) {
additionalItemsSupport = true;
} else if (prefixItems == null && !(items instanceof Boolean)) {
additionalItemsSupport = true;
}
this.additionalItems = additionalItemsSupport;
if (prefixItems == null) {
this.prefixItems = new JSONSchema[0];
} else {
this.prefixItems = new JSONSchema[prefixItems.size()];
for (int i = 0; i < prefixItems.size(); i++) {
JSONSchema schema;
Object prefixItem = prefixItems.get(i);
if (prefixItem instanceof Boolean) {
schema = (Boolean) prefixItem ? Any.INSTANCE : Any.NOT_ANY;
} else {
JSONObject jsonObject = (JSONObject) prefixItem;
schema = JSONSchema.of(jsonObject, root == null ? this : root);
}
this.prefixItems[i] = schema;
}
}
this.contains = input.getObject("contains", JSONSchema::of);
this.minContains = input.getIntValue("minContains", -1);
this.maxContains = input.getIntValue("maxContains", -1);
this.uniqueItems = input.getBooleanValue("uniqueItems");
allOf = allOf(input, null);
anyOf = anyOf(input, null);
oneOf = oneOf(input, null);
}
@Override
public Type getType() {
return Type.Array;
}
@Override
public ValidateResult validate(Object value) {
if (value == null) {
return typed ? FAIL_INPUT_NULL : SUCCESS;
}
if (encoded) {
if (value instanceof String) {
try {
value = JSON.parseArray((String) value);
} catch (JSONException e) {
return FAIL_INPUT_NOT_ENCODED;
}
} else {
return FAIL_INPUT_NOT_ENCODED;
}
}
if (value instanceof Object[]) {
final Object[] items = (Object[]) value;
return validateItems(value, items.length, i -> items[i]);
}
if (value.getClass().isArray()) {
final int size = Array.getLength(value);
final Object finalValue = value;
return validateItems(finalValue, size, i -> Array.get(finalValue, i));
}
if (value instanceof Collection) {
final Collection> items = (Collection>) value;
final Iterator> iterator = items.iterator();
return validateItems(value, items.size(), i -> iterator.next());
}
return typed ? FAIL_TYPE_NOT_MATCH : SUCCESS;
}
private ValidateResult validateItems(final Object value, final int size, IntFunction