21
21
import java .util .EnumSet ;
22
22
import java .util .List ;
23
23
24
- import org .springframework .data .mapping .PersistentEntity ;
25
24
import org .springframework .data .mapping .PersistentProperty ;
26
- import org .springframework .data .mapping .SimplePropertyHandler ;
27
25
import org .springframework .data .mapping .context .MappingContext ;
28
26
import org .springframework .data .mongodb .core .convert .MongoConverter ;
29
27
import org .springframework .data .mongodb .core .mapping .Field ;
28
+ import org .springframework .data .mongodb .core .mapping .MongoPersistentEntity ;
30
29
import org .springframework .data .mongodb .core .mapping .MongoPersistentProperty ;
31
30
import org .springframework .data .mongodb .core .schema .IdentifiableJsonSchemaProperty .ObjectJsonSchemaProperty ;
32
31
import org .springframework .data .mongodb .core .schema .JsonSchemaObject ;
35
34
import org .springframework .data .mongodb .core .schema .MongoJsonSchema ;
36
35
import org .springframework .data .mongodb .core .schema .MongoJsonSchema .MongoJsonSchemaBuilder ;
37
36
import org .springframework .data .mongodb .core .schema .TypedJsonSchemaObject ;
38
- import org .springframework .lang .Nullable ;
39
37
import org .springframework .util .Assert ;
40
38
import org .springframework .util .ClassUtils ;
41
39
import org .springframework .util .CollectionUtils ;
45
43
* {@link MongoJsonSchemaCreator} implementation using both {@link MongoConverter} and {@link MappingContext} to obtain
46
44
* domain type meta information which considers {@link org.springframework.data.mongodb.core.mapping.Field field names}
47
45
* and {@link org.springframework.data.mongodb.core.convert.MongoCustomConversions custom conversions}.
48
- *
46
+ *
49
47
* @author Christoph Strobl
48
+ * @author Mark Paluch
50
49
* @since 2.2
51
50
*/
52
51
class MappingMongoJsonSchemaCreator implements MongoJsonSchemaCreator {
53
52
54
- private MongoConverter converter ;
55
- private MappingContext mappingContext ;
53
+ private final MongoConverter converter ;
54
+ private final MappingContext < MongoPersistentEntity <?>, MongoPersistentProperty > mappingContext ;
56
55
57
56
/**
58
57
* Create a new instance of {@link MappingMongoJsonSchemaCreator}.
59
58
*
60
59
* @param converter must not be {@literal null}.
61
60
*/
61
+ @ SuppressWarnings ("unchecked" )
62
62
MappingMongoJsonSchemaCreator (MongoConverter converter ) {
63
63
64
64
Assert .notNull (converter , "Converter must not be null!" );
65
65
this .converter = converter ;
66
- this .mappingContext = converter . getMappingContext ();
67
-
66
+ this .mappingContext = ( MappingContext < MongoPersistentEntity <?>, MongoPersistentProperty >) converter
67
+ . getMappingContext ();
68
68
}
69
69
70
70
/*
@@ -74,7 +74,7 @@ class MappingMongoJsonSchemaCreator implements MongoJsonSchemaCreator {
74
74
@ Override
75
75
public MongoJsonSchema createSchemaFor (Class <?> type ) {
76
76
77
- PersistentEntity <?, ? > entity = mappingContext .getPersistentEntity (type );
77
+ MongoPersistentEntity <? > entity = mappingContext .getRequiredPersistentEntity (type );
78
78
MongoJsonSchemaBuilder schemaBuilder = MongoJsonSchema .builder ();
79
79
80
80
List <JsonSchemaProperty > schemaProperties = computePropertiesForEntity (Collections .emptyList (), entity );
@@ -84,35 +84,33 @@ public MongoJsonSchema createSchemaFor(Class<?> type) {
84
84
85
85
}
86
86
87
- private List <JsonSchemaProperty > computePropertiesForEntity (List <PersistentProperty > path ,
88
- PersistentEntity <?, ?> entity ) {
87
+ private List <JsonSchemaProperty > computePropertiesForEntity (List <MongoPersistentProperty > path ,
88
+ MongoPersistentEntity < ?> entity ) {
89
89
90
90
List <JsonSchemaProperty > schemaProperties = new ArrayList <>();
91
- entity .doWithProperties ((SimplePropertyHandler ) nested -> {
92
91
93
- ArrayList <PersistentProperty > currentPath = new ArrayList <>(path );
92
+ for (MongoPersistentProperty nested : entity ) {
93
+
94
+ List <MongoPersistentProperty > currentPath = new ArrayList <>(path );
94
95
95
96
if (path .contains (nested )) { // cycle guard
96
97
schemaProperties .add (createSchemaProperty (computePropertyFieldName (CollectionUtils .lastElement (currentPath )),
97
98
Object .class , false ));
98
- return ;
99
+ break ;
99
100
}
100
101
101
102
currentPath .add (nested );
102
- JsonSchemaProperty jsonSchemaProperty = computeSchemaForProperty (currentPath , entity );
103
- if (jsonSchemaProperty != null ) {
104
- schemaProperties .add (jsonSchemaProperty );
105
- }
106
- });
103
+ schemaProperties .add (computeSchemaForProperty (currentPath ));
104
+ }
107
105
108
106
return schemaProperties ;
109
107
}
110
108
111
- private JsonSchemaProperty computeSchemaForProperty (List <PersistentProperty > path , PersistentEntity <?, ?> parent ) {
109
+ private JsonSchemaProperty computeSchemaForProperty (List <MongoPersistentProperty > path ) {
112
110
113
- PersistentProperty property = CollectionUtils .lastElement (path );
111
+ MongoPersistentProperty property = CollectionUtils .lastElement (path );
114
112
115
- boolean required = isRequiredProperty (parent , property );
113
+ boolean required = isRequiredProperty (property );
116
114
Class <?> rawTargetType = computeTargetType (property ); // target type before conversion
117
115
Class <?> targetType = converter .getTypeMapper ().getWriteTargetTypeFor (rawTargetType ); // conversion target type
118
116
@@ -133,12 +131,12 @@ private JsonSchemaProperty computeSchemaForProperty(List<PersistentProperty> pat
133
131
return createSchemaProperty (fieldName , targetType , required );
134
132
}
135
133
136
- private JsonSchemaProperty createObjectSchemaPropertyForEntity (List <PersistentProperty > path ,
137
- PersistentProperty property , boolean required ) {
134
+ private JsonSchemaProperty createObjectSchemaPropertyForEntity (List <MongoPersistentProperty > path ,
135
+ MongoPersistentProperty property , boolean required ) {
138
136
139
137
ObjectJsonSchemaProperty target = JsonSchemaProperty .object (property .getName ());
140
138
List <JsonSchemaProperty > nestedProperties = computePropertiesForEntity (path ,
141
- mappingContext .getPersistentEntity (property ));
139
+ mappingContext .getRequiredPersistentEntity (property ));
142
140
143
141
return createPotentiallyRequiredSchemaProperty (
144
142
target .properties (nestedProperties .toArray (new JsonSchemaProperty [0 ])), required );
@@ -147,6 +145,7 @@ private JsonSchemaProperty createObjectSchemaPropertyForEntity(List<PersistentPr
147
145
private JsonSchemaProperty createEnumSchemaProperty (String fieldName , Class <?> targetType , boolean required ) {
148
146
149
147
List <Object > possibleValues = new ArrayList <>();
148
+
150
149
for (Object enumValue : EnumSet .allOf ((Class ) targetType )) {
151
150
possibleValues .add (converter .convertToMongoType (enumValue ));
152
151
}
@@ -178,10 +177,8 @@ private String computePropertyFieldName(PersistentProperty property) {
178
177
: property .getName ();
179
178
}
180
179
181
- private boolean isRequiredProperty (PersistentEntity <?, ?> parent , PersistentProperty property ) {
182
-
183
- return (parent .isConstructorArgument (property ) && !property .isAnnotationPresent (Nullable .class ))
184
- || property .getType ().isPrimitive ();
180
+ private boolean isRequiredProperty (PersistentProperty property ) {
181
+ return property .getType ().isPrimitive ();
185
182
}
186
183
187
184
private Class <?> computeTargetType (PersistentProperty <?> property ) {
@@ -196,7 +193,7 @@ private Class<?> computeTargetType(PersistentProperty<?> property) {
196
193
}
197
194
198
195
if (mongoProperty .hasExplicitWriteTarget ()) {
199
- return mongoProperty .findAnnotation (Field .class ).targetType ().getJavaClass ();
196
+ return mongoProperty .getRequiredAnnotation (Field .class ).targetType ().getJavaClass ();
200
197
}
201
198
202
199
return mongoProperty .getFieldType () != mongoProperty .getActualType () ? Object .class : mongoProperty .getFieldType ();
0 commit comments