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

org.springframework.data.mongodb.core.schema.JsonSchemaObject Maven / Gradle / Ivy

There is a newer version: 4.2.5
Show newest version
/*
 * Copyright 2018-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.mongodb.core.schema;

import lombok.EqualsAndHashCode;
import lombok.RequiredArgsConstructor;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

import org.bson.BsonTimestamp;
import org.bson.Document;
import org.bson.types.BSONTimestamp;
import org.bson.types.Binary;
import org.bson.types.Code;
import org.bson.types.Decimal128;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.ArrayJsonSchemaObject;
import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.BooleanJsonSchemaObject;
import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.DateJsonSchemaObject;
import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.NullJsonSchemaObject;
import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.NumericJsonSchemaObject;
import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.ObjectJsonSchemaObject;
import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.StringJsonSchemaObject;
import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.TimestampJsonSchemaObject;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;

/**
 * Interface that can be implemented by objects that know how to serialize themselves to JSON schema using
 * {@link #toDocument()}.
 * 

* This class also declares factory methods for type-specific {@link JsonSchemaObject schema objects} such as * {@link #string()} or {@link #object()}. For example: * *

 * JsonSchemaProperty.object("address").properties(JsonSchemaProperty.string("city").minLength(3));
 * 
* * @author Christoph Strobl * @author Mark Paluch * @since 2.1 */ public interface JsonSchemaObject { /** * Get the set of types defined for this schema element.
* The {@link Set} is likely to contain only one element in most cases. * * @return never {@literal null}. */ Set getTypes(); /** * Get the MongoDB specific representation.
* The Document may contain fields (eg. like {@literal bsonType}) not contained in the JsonSchema specification. It * may also contain types not directly processable by the MongoDB java driver. Make sure to run the produced * {@link Document} through the mapping infrastructure. * * @return never {@literal null}. */ Document toDocument(); /** * Create a new {@link JsonSchemaObject} of {@code type : 'object'}. * * @return never {@literal null}. */ static ObjectJsonSchemaObject object() { return new ObjectJsonSchemaObject(); } /** * Create a new {@link JsonSchemaObject} of {@code type : 'string'}. * * @return never {@literal null}. */ static StringJsonSchemaObject string() { return new StringJsonSchemaObject(); } /** * Create a new {@link JsonSchemaObject} of {@code type : 'number'}. * * @return never {@literal null}. */ static NumericJsonSchemaObject number() { return new NumericJsonSchemaObject(); } /** * Create a new {@link JsonSchemaObject} of {@code type : 'array'}. * * @return never {@literal null}. */ static ArrayJsonSchemaObject array() { return new ArrayJsonSchemaObject(); } /** * Create a new {@link JsonSchemaObject} of {@code type : 'boolean'}. * * @return never {@literal null}. */ static BooleanJsonSchemaObject bool() { return new BooleanJsonSchemaObject(); } /** * Create a new {@link JsonSchemaObject} of {@code type : 'null'}. * * @return never {@literal null}. */ static NullJsonSchemaObject nil() { return new NullJsonSchemaObject(); } /** * Create a new {@link JsonSchemaObject} of {@code type : 'date'}. * * @return never {@literal null}. */ static DateJsonSchemaObject date() { return new DateJsonSchemaObject(); } /** * Create a new {@link JsonSchemaObject} of {@code type : 'timestamp'}. * * @return never {@literal null}. */ static TimestampJsonSchemaObject timestamp() { return new TimestampJsonSchemaObject(); } /** * Create a new {@link JsonSchemaObject} of given {@link Type}. * * @return never {@literal null}. */ static TypedJsonSchemaObject of(Type type) { return TypedJsonSchemaObject.of(type); } /** * Create a new {@link UntypedJsonSchemaObject}. * * @return never {@literal null}. */ static UntypedJsonSchemaObject untyped() { return new UntypedJsonSchemaObject(null, null, false); } /** * Create a new {@link JsonSchemaObject} matching the given {@code type}. * * @param type Java class to create a {@link JsonSchemaObject} for. May be {@literal null} to create * {@link Type#nullType() null} type. * @return never {@literal null}. * @throws IllegalArgumentException if {@code type} is not supported. */ static TypedJsonSchemaObject of(@Nullable Class type) { if (type == null) { return of(Type.nullType()); } if (type.isArray() || ClassUtils.isAssignable(Collection.class, type)) { if (type.equals(byte[].class)) { return of(Type.binaryType()); } return of(Type.arrayType()); } if (type.equals(Document.class) || ClassUtils.isAssignable(Map.class, type)) { return of(Type.objectType()); } if (type.equals(Object.class)) { return of(Type.objectType()); } if (type.equals(ObjectId.class)) { return of(Type.objectIdType()); } if (ClassUtils.isAssignable(String.class, type)) { return of(Type.stringType()); } if (ClassUtils.isAssignable(Date.class, type)) { return of(Type.dateType()); } if (ClassUtils.isAssignable(Binary.class, type)) { return of(Type.binaryType()); } if (ClassUtils.isAssignable(Code.class, type)) { return of(Type.javascriptType()); } if (ClassUtils.isAssignable(Decimal128.class, type)) { return of(Type.bigDecimalType()); } if (ClassUtils.isAssignable(BsonTimestamp.class, type) || ClassUtils.isAssignable(BSONTimestamp.class, type)) { return of(Type.timestampType()); } if (ClassUtils.isAssignable(Pattern.class, type)) { return of(Type.regexType()); } if (ClassUtils.isAssignable(Enum.class, type)) { return of(Type.stringType()); } Class resolved = ClassUtils.resolvePrimitiveIfNecessary(type); if (ClassUtils.isAssignable(Boolean.class, resolved)) { return of(Type.booleanType()); } if (ClassUtils.isAssignable(Number.class, resolved)) { if (resolved.equals(Long.class)) { return of(Type.longType()); } if (resolved.equals(Float.class)) { return of(Type.doubleType()); } if (resolved.equals(Double.class)) { return of(Type.doubleType()); } if (resolved.equals(Integer.class)) { return of(Type.intType()); } if (resolved.equals(BigDecimal.class)) { return of(Type.bigDecimalType()); } return of(Type.numberType()); } throw new IllegalArgumentException(String.format("No JSON schema type found for %s.", type)); } /** * Type represents either a JSON schema {@literal type} or a MongoDB specific {@literal bsonType}. * * @author Christoph Strobl * @since 2.1 */ interface Type { // BSON TYPES Type OBJECT_ID = bsonTypeOf("objectId"); Type REGULAR_EXPRESSION = bsonTypeOf("regex"); Type DOUBLE = bsonTypeOf("double"); Type BINARY_DATA = bsonTypeOf("binData"); Type DATE = bsonTypeOf("date"); Type JAVA_SCRIPT = bsonTypeOf("javascript"); Type INT_32 = bsonTypeOf("int"); Type INT_64 = bsonTypeOf("long"); Type DECIMAL_128 = bsonTypeOf("decimal"); Type TIMESTAMP = bsonTypeOf("timestamp"); Set BSON_TYPES = new HashSet<>(Arrays.asList(OBJECT_ID, REGULAR_EXPRESSION, DOUBLE, BINARY_DATA, DATE, JAVA_SCRIPT, INT_32, INT_64, DECIMAL_128, TIMESTAMP)); // JSON SCHEMA TYPES Type OBJECT = jsonTypeOf("object"); Type ARRAY = jsonTypeOf("array"); Type NUMBER = jsonTypeOf("number"); Type BOOLEAN = jsonTypeOf("boolean"); Type STRING = jsonTypeOf("string"); Type NULL = jsonTypeOf("null"); Set JSON_TYPES = new HashSet<>(Arrays.asList(OBJECT, ARRAY, NUMBER, BOOLEAN, STRING, NULL)); /** * @return a constant {@link Type} representing {@code bsonType : 'objectId' }. */ static Type objectIdType() { return OBJECT_ID; } /** * @return a constant {@link Type} representing {@code bsonType : 'regex' }. */ static Type regexType() { return REGULAR_EXPRESSION; } /** * @return a constant {@link Type} representing {@code bsonType : 'double' }. */ static Type doubleType() { return DOUBLE; } /** * @return a constant {@link Type} representing {@code bsonType : 'binData' }. */ static Type binaryType() { return BINARY_DATA; } /** * @return a constant {@link Type} representing {@code bsonType : 'date' }. */ static Type dateType() { return DATE; } /** * @return a constant {@link Type} representing {@code bsonType : 'javascript' }. */ static Type javascriptType() { return JAVA_SCRIPT; } /** * @return a constant {@link Type} representing {@code bsonType : 'int' }. */ static Type intType() { return INT_32; } /** * @return a constant {@link Type} representing {@code bsonType : 'long' }. */ static Type longType() { return INT_64; } /** * @return a constant {@link Type} representing {@code bsonType : 'decimal128' }. */ static Type bigDecimalType() { return DECIMAL_128; } /** * @return a constant {@link Type} representing {@code bsonType : 'timestamp' }. */ static Type timestampType() { return TIMESTAMP; } /** * @return a constant {@link Type} representing {@code type : 'object' }. */ static Type objectType() { return OBJECT; } /** * @return a constant {@link Type} representing {@code type : 'array' }. */ static Type arrayType() { return ARRAY; } /** * @return a constant {@link Type} representing {@code type : 'number' }. */ static Type numberType() { return NUMBER; } /** * @return a constant {@link Type} representing {@code type : 'boolean' }. */ static Type booleanType() { return BOOLEAN; } /** * @return a constant {@link Type} representing {@code type : 'string' }. */ static Type stringType() { return STRING; } /** * @return a constant {@link Type} representing {@code type : 'null' }. */ static Type nullType() { return NULL; } /** * @return new {@link Type} representing the given {@code bsonType}. */ static Type bsonTypeOf(String name) { return new BsonType(name); } /** * @return new {@link Type} representing the given {@code type}. */ static Type jsonTypeOf(String name) { return new JsonType(name); } /** * Create a {@link Type} with its default {@link Type#representation() representation} via the name. * * @param name must not be {@literal null}. * @return the matching type instance. * @since 2.2 */ static Type of(String name) { Type type = jsonTypeOf(name); if (jsonTypes().contains(type)) { return type; } return bsonTypeOf(name); } /** * @return all known JSON types. */ static Set jsonTypes() { return JSON_TYPES; } /** * @return all known BSON types. */ static Set bsonTypes() { return BSON_TYPES; } /** * Get the {@link Type} representation. Either {@code type} or {@code bsonType}. * * @return never {@literal null}. */ String representation(); /** * Get the {@link Type} value. Like {@literal string}, {@literal number},... * * @return never {@literal null}. */ Object value(); /** * Get the {@literal bsonType} representation of the given type. * * @return never {@literal null}. * @since 2.2 */ default Type toBsonType() { if (representation().equals("bsonType")) { return this; } if (value().equals(Type.booleanType().value())) { return bsonTypeOf("bool"); } if (value().equals(Type.numberType().value())) { return bsonTypeOf("long"); } return bsonTypeOf((String) value()); } /** * @author Christpoh Strobl * @since 2.1 */ @RequiredArgsConstructor @EqualsAndHashCode class JsonType implements Type { private final String name; /* * (non-Javadoc) * @see org.springframework.data.mongodb.core.schema.JsonSchemaObject.Type#representation() */ @Override public String representation() { return "type"; } /* * (non-Javadoc) * @see org.springframework.data.mongodb.core.schema.JsonSchemaObject.Type#value() */ @Override public String value() { return name; } } /** * @author Christpoh Strobl * @since 2.1 */ @RequiredArgsConstructor @EqualsAndHashCode class BsonType implements Type { private final String name; /* * (non-Javadoc) * @see org.springframework.data.mongodb.core.schema.JsonSchemaObject.Type#representation() */ @Override public String representation() { return "bsonType"; } /* * (non-Javadoc) * @see org.springframework.data.mongodb.core.schema.JsonSchemaObject.Type#value() */ @Override public String value() { return name; } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy