27
27
import org .springframework .data .mapping .PersistentProperty ;
28
28
import org .springframework .data .mapping .context .MappingContext ;
29
29
import org .springframework .data .mongodb .core .convert .MongoConverter ;
30
- import org .springframework .data .mongodb .core .mapping .BasicMongoPersistentEntity ;
31
30
import org .springframework .data .mongodb .core .mapping .Encrypted ;
32
31
import org .springframework .data .mongodb .core .mapping .Field ;
33
32
import org .springframework .data .mongodb .core .mapping .MongoPersistentEntity ;
34
33
import org .springframework .data .mongodb .core .mapping .MongoPersistentProperty ;
34
+ import org .springframework .data .mongodb .core .schema .IdentifiableJsonSchemaProperty .ArrayJsonSchemaProperty ;
35
35
import org .springframework .data .mongodb .core .schema .IdentifiableJsonSchemaProperty .EncryptedJsonSchemaProperty ;
36
36
import org .springframework .data .mongodb .core .schema .IdentifiableJsonSchemaProperty .ObjectJsonSchemaProperty ;
37
37
import org .springframework .data .mongodb .core .schema .JsonSchemaObject ;
@@ -160,15 +160,15 @@ private JsonSchemaProperty computeSchemaForProperty(List<MongoPersistentProperty
160
160
Class <?> rawTargetType = computeTargetType (property ); // target type before conversion
161
161
Class <?> targetType = converter .getTypeMapper ().getWriteTargetTypeFor (rawTargetType ); // conversion target type
162
162
163
- if (property .isEntity () && ObjectUtils .nullSafeEquals (rawTargetType , targetType )) {
163
+ if (! isCollection ( property ) && property .isEntity () && ObjectUtils .nullSafeEquals (rawTargetType , targetType )) {
164
164
return createObjectSchemaPropertyForEntity (path , property , required );
165
165
}
166
166
167
167
String fieldName = computePropertyFieldName (property );
168
168
169
169
JsonSchemaProperty schemaProperty ;
170
- if (property . isCollectionLike ( )) {
171
- schemaProperty = createSchemaProperty (fieldName , targetType , required );
170
+ if (isCollection ( property )) {
171
+ schemaProperty = createSchemaPropertyForCollection (fieldName , property , required );
172
172
} else if (property .isMap ()) {
173
173
schemaProperty = createSchemaProperty (fieldName , Type .objectType (), required );
174
174
} else if (ClassUtils .isAssignable (Enum .class , targetType )) {
@@ -180,6 +180,48 @@ private JsonSchemaProperty computeSchemaForProperty(List<MongoPersistentProperty
180
180
return applyEncryptionDataIfNecessary (property , schemaProperty );
181
181
}
182
182
183
+ private JsonSchemaProperty createSchemaPropertyForCollection (String fieldName , MongoPersistentProperty property ,
184
+ boolean required ) {
185
+
186
+ ArrayJsonSchemaProperty schemaProperty = JsonSchemaProperty .array (fieldName );
187
+
188
+ if (property .getActualType () != Object .class ) {
189
+
190
+ MongoPersistentEntity <?> persistentEntity = mappingContext
191
+ .getPersistentEntity (property .getTypeInformation ().getComponentType ());
192
+
193
+ if (persistentEntity == null ) {
194
+
195
+ if (ClassUtils .isAssignable (Enum .class , property .getActualType ())) {
196
+
197
+ List <Object > possibleValues = new ArrayList <>();
198
+
199
+ for (Object enumValue : EnumSet .allOf ((Class ) property .getActualType ())) {
200
+ possibleValues .add (converter .convertToMongoType (enumValue ));
201
+ }
202
+
203
+ Class targetType = possibleValues .isEmpty () ? property .getActualType ()
204
+ : possibleValues .iterator ().next ().getClass ();
205
+ schemaProperty = schemaProperty
206
+ .items (Collections .singleton (JsonSchemaObject .of (targetType ).possibleValues (possibleValues )));
207
+ } else {
208
+ schemaProperty = schemaProperty .items (Collections .singleton (JsonSchemaObject .of (property .getActualType ())));
209
+ }
210
+ } else {
211
+
212
+ List <JsonSchemaProperty > nestedProperties = computePropertiesForEntity (Collections .emptyList (),
213
+ persistentEntity );
214
+
215
+ if (!nestedProperties .isEmpty ()) {
216
+ schemaProperty = schemaProperty .items (Collections
217
+ .singleton (JsonSchemaObject .object ().properties (nestedProperties .toArray (new JsonSchemaProperty [0 ]))));
218
+ }
219
+ }
220
+ }
221
+
222
+ return createPotentiallyRequiredSchemaProperty (schemaProperty , required );
223
+ }
224
+
183
225
@ Nullable
184
226
private JsonSchemaProperty applyEncryptionDataIfNecessary (MongoPersistentProperty property ,
185
227
JsonSchemaProperty schemaProperty ) {
@@ -197,7 +239,6 @@ private JsonSchemaProperty applyEncryptionDataIfNecessary(MongoPersistentPropert
197
239
enc = enc .keys (property .getEncryptionKeyIds ());
198
240
}
199
241
return enc ;
200
-
201
242
}
202
243
203
244
private JsonSchemaProperty createObjectSchemaPropertyForEntity (List <MongoPersistentProperty > path ,
@@ -268,6 +309,10 @@ private Class<?> computeTargetType(PersistentProperty<?> property) {
268
309
return mongoProperty .getFieldType () != mongoProperty .getActualType () ? Object .class : mongoProperty .getFieldType ();
269
310
}
270
311
312
+ private static boolean isCollection (MongoPersistentProperty property ) {
313
+ return property .isCollectionLike () && !property .getType ().equals (byte [].class );
314
+ }
315
+
271
316
static JsonSchemaProperty createPotentiallyRequiredSchemaProperty (JsonSchemaProperty property , boolean required ) {
272
317
273
318
if (!required ) {
0 commit comments