Render items for collection-like properties when deriving $jsonSchema.
Closes #3766 Original pull request: #3837.
This commit is contained in:
committed by
Mark Paluch
parent
c0a4bdb548
commit
bbe8410979
@@ -27,11 +27,11 @@ import org.bson.Document;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverter;
|
||||
import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.Encrypted;
|
||||
import org.springframework.data.mongodb.core.mapping.Field;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.ArrayJsonSchemaProperty;
|
||||
import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.EncryptedJsonSchemaProperty;
|
||||
import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.ObjectJsonSchemaProperty;
|
||||
import org.springframework.data.mongodb.core.schema.JsonSchemaObject;
|
||||
@@ -160,15 +160,15 @@ class MappingMongoJsonSchemaCreator implements MongoJsonSchemaCreator {
|
||||
Class<?> rawTargetType = computeTargetType(property); // target type before conversion
|
||||
Class<?> targetType = converter.getTypeMapper().getWriteTargetTypeFor(rawTargetType); // conversion target type
|
||||
|
||||
if (property.isEntity() && ObjectUtils.nullSafeEquals(rawTargetType, targetType)) {
|
||||
if (!isCollection(property) && property.isEntity() && ObjectUtils.nullSafeEquals(rawTargetType, targetType)) {
|
||||
return createObjectSchemaPropertyForEntity(path, property, required);
|
||||
}
|
||||
|
||||
String fieldName = computePropertyFieldName(property);
|
||||
|
||||
JsonSchemaProperty schemaProperty;
|
||||
if (property.isCollectionLike()) {
|
||||
schemaProperty = createSchemaProperty(fieldName, targetType, required);
|
||||
if (isCollection(property)) {
|
||||
schemaProperty = createSchemaPropertyForCollection(fieldName, property, required);
|
||||
} else if (property.isMap()) {
|
||||
schemaProperty = createSchemaProperty(fieldName, Type.objectType(), required);
|
||||
} else if (ClassUtils.isAssignable(Enum.class, targetType)) {
|
||||
@@ -180,6 +180,48 @@ class MappingMongoJsonSchemaCreator implements MongoJsonSchemaCreator {
|
||||
return applyEncryptionDataIfNecessary(property, schemaProperty);
|
||||
}
|
||||
|
||||
private JsonSchemaProperty createSchemaPropertyForCollection(String fieldName, MongoPersistentProperty property,
|
||||
boolean required) {
|
||||
|
||||
ArrayJsonSchemaProperty schemaProperty = JsonSchemaProperty.array(fieldName);
|
||||
|
||||
if (property.getActualType() != Object.class) {
|
||||
|
||||
MongoPersistentEntity<?> persistentEntity = mappingContext
|
||||
.getPersistentEntity(property.getTypeInformation().getComponentType());
|
||||
|
||||
if (persistentEntity == null) {
|
||||
|
||||
if (ClassUtils.isAssignable(Enum.class, property.getActualType())) {
|
||||
|
||||
List<Object> possibleValues = new ArrayList<>();
|
||||
|
||||
for (Object enumValue : EnumSet.allOf((Class) property.getActualType())) {
|
||||
possibleValues.add(converter.convertToMongoType(enumValue));
|
||||
}
|
||||
|
||||
Class targetType = possibleValues.isEmpty() ? property.getActualType()
|
||||
: possibleValues.iterator().next().getClass();
|
||||
schemaProperty = schemaProperty
|
||||
.items(Collections.singleton(JsonSchemaObject.of(targetType).possibleValues(possibleValues)));
|
||||
} else {
|
||||
schemaProperty = schemaProperty.items(Collections.singleton(JsonSchemaObject.of(property.getActualType())));
|
||||
}
|
||||
} else {
|
||||
|
||||
List<JsonSchemaProperty> nestedProperties = computePropertiesForEntity(Collections.emptyList(),
|
||||
persistentEntity);
|
||||
|
||||
if (!nestedProperties.isEmpty()) {
|
||||
schemaProperty = schemaProperty.items(Collections
|
||||
.singleton(JsonSchemaObject.object().properties(nestedProperties.toArray(new JsonSchemaProperty[0]))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return createPotentiallyRequiredSchemaProperty(schemaProperty, required);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private JsonSchemaProperty applyEncryptionDataIfNecessary(MongoPersistentProperty property,
|
||||
JsonSchemaProperty schemaProperty) {
|
||||
@@ -197,7 +239,6 @@ class MappingMongoJsonSchemaCreator implements MongoJsonSchemaCreator {
|
||||
enc = enc.keys(property.getEncryptionKeyIds());
|
||||
}
|
||||
return enc;
|
||||
|
||||
}
|
||||
|
||||
private JsonSchemaProperty createObjectSchemaPropertyForEntity(List<MongoPersistentProperty> path,
|
||||
@@ -268,6 +309,10 @@ class MappingMongoJsonSchemaCreator implements MongoJsonSchemaCreator {
|
||||
return mongoProperty.getFieldType() != mongoProperty.getActualType() ? Object.class : mongoProperty.getFieldType();
|
||||
}
|
||||
|
||||
private static boolean isCollection(MongoPersistentProperty property) {
|
||||
return property.isCollectionLike() && !property.getType().equals(byte[].class);
|
||||
}
|
||||
|
||||
static JsonSchemaProperty createPotentiallyRequiredSchemaProperty(JsonSchemaProperty property, boolean required) {
|
||||
|
||||
if (!required) {
|
||||
|
||||
@@ -185,6 +185,9 @@ public class MappingMongoJsonSchemaCreatorUnitTests {
|
||||
" 'arrayProperty' : { 'type' : 'array' }," + //
|
||||
" 'binaryDataProperty' : { 'bsonType' : 'binData' }," + //
|
||||
" 'collectionProperty' : { 'type' : 'array' }," + //
|
||||
" 'simpleTypeCollectionProperty' : { 'type' : 'array', 'items' : { 'type' : 'string' } }," + //
|
||||
" 'complexTypeCollectionProperty' : { 'type' : 'array', 'items' : { 'type' : 'object', 'properties' : { 'field' : { 'type' : 'string'} } } }" + //
|
||||
" 'enumTypeCollectionProperty' : { 'type' : 'array', 'items' : " + JUST_SOME_ENUM + " }" + //
|
||||
" 'mapProperty' : { 'type' : 'object' }," + //
|
||||
" 'objectProperty' : { 'type' : 'object' }," + //
|
||||
" 'enumProperty' : " + JUST_SOME_ENUM + " }" + //
|
||||
@@ -203,12 +206,19 @@ public class MappingMongoJsonSchemaCreatorUnitTests {
|
||||
Date dateProperty;
|
||||
Object[] arrayProperty;
|
||||
byte[] binaryDataProperty;
|
||||
List<String> collectionProperty;
|
||||
List<Object> collectionProperty;
|
||||
List<String> simpleTypeCollectionProperty;
|
||||
List<SomeDomainType> complexTypeCollectionProperty;
|
||||
List<JustSomeEnum> enumTypeCollectionProperty;
|
||||
Map<String, String> mapProperty;
|
||||
Object objectProperty;
|
||||
JustSomeEnum enumProperty;
|
||||
}
|
||||
|
||||
static class SomeDomainType {
|
||||
String field;
|
||||
}
|
||||
|
||||
// --> NESTED DOMAIN TYPE
|
||||
|
||||
static final String WITH_NESTED_DOMAIN_TYPE = "" + //
|
||||
|
||||
Reference in New Issue
Block a user