16
16
17
17
package org .bson .codecs .pojo ;
18
18
19
+ import org .bson .codecs .configuration .CodecConfigurationException ;
20
+
19
21
import java .lang .annotation .Annotation ;
20
22
import java .util .ArrayList ;
21
23
import java .util .Collections ;
41
43
* @see ClassModel
42
44
*/
43
45
public class ClassModelBuilder <T > {
44
- private static final String ID_FIELD_NAME = "_id" ;
45
- private final List <FieldModelBuilder <?>> fields = new ArrayList <FieldModelBuilder <?>>();
46
+ private static final String ID_PROPERTY_NAME = "_id" ;
47
+ private final List <PropertyModelBuilder <?>> propertyModelBuilders = new ArrayList <PropertyModelBuilder <?>>();
46
48
private InstanceCreatorFactory <T > instanceCreatorFactory ;
47
49
private Class <T > type ;
48
- private Map <String , TypeParameterMap > fieldNameToTypeParameterMap = emptyMap ();
50
+ private Map <String , TypeParameterMap > propertyNameToTypeParameterMap = emptyMap ();
49
51
private List <Convention > conventions = DEFAULT_CONVENTIONS ;
50
52
private List <Annotation > annotations = emptyList ();
51
53
private boolean discriminatorEnabled ;
52
54
private String discriminator ;
53
55
private String discriminatorKey ;
54
- private String idField ;
56
+ private String idPropertyName ;
55
57
56
58
ClassModelBuilder (final Class <T > type ) {
57
59
configureClassModelBuilder (this , notNull ("type" , type ));
@@ -184,59 +186,56 @@ public Boolean useDiscriminator() {
184
186
}
185
187
186
188
/**
187
- * Designates a field as the {@code _id} field for this type. If another field is currently marked as the {@code _id} field,
188
- * that setting is cleared in favor of the named field.
189
+ * Designates a property as the {@code _id} property for this type. If another property is currently marked as the {@code _id}
190
+ * property, that setting is cleared in favor of the named property.
191
+ *
192
+ * @param idPropertyName the property name to use for the {@code _id} property
189
193
*
190
- * @param idField the FieldModel field name to use for the {@code _id} field
191
194
* @return this
192
195
*/
193
- public ClassModelBuilder <T > idField (final String idField ) {
194
- this .idField = notNull ("idField " , idField );
196
+ public ClassModelBuilder <T > idPropertyName (final String idPropertyName ) {
197
+ this .idPropertyName = notNull ("idPropertyName " , idPropertyName );
195
198
return this ;
196
199
}
197
200
198
201
/**
199
- * @return the designated {@code _id} field for this type or null if not set
202
+ * @return the designated {@code _id} property name for this type or null if not set
200
203
*/
201
- public String getIdField () {
202
- return idField ;
204
+ public String getIdPropertyName () {
205
+ return idPropertyName ;
203
206
}
204
207
205
208
/**
206
- * Remove a field from the builder
209
+ * Remove a property from the builder
207
210
*
208
- * @param name the actual field name in the POJO and not the {@code documentFieldName }.
209
- * @return returns true if the field matched and was removed
211
+ * @param propertyName the actual property name in the POJO and not the {@code documentPropertyName }.
212
+ * @return returns true if the property matched and was removed
210
213
*/
211
- public boolean removeField (final String name ) {
212
- return fields .remove (getField (notNull ("name " , name )));
214
+ public boolean removeProperty (final String propertyName ) {
215
+ return propertyModelBuilders .remove (getProperty (notNull ("propertyName " , propertyName )));
213
216
}
214
217
215
218
/**
216
- * Gets a field by the given name.
217
- *
218
- * <p>
219
- * Note: Searches against the actual field name in the POJO and not the {@code documentFieldName}.
220
- * </p>
219
+ * Gets a property by the property name.
221
220
*
222
- * @param name the name of the field to find.
223
- * @return the field or null if the field is not found
221
+ * @param propertyName the name of the property to find.
222
+ * @return the property or null if the property is not found
224
223
*/
225
- public FieldModelBuilder <?> getField (final String name ) {
226
- notNull ("name " , name );
227
- for (FieldModelBuilder <?> fieldModelBuilder : fields ) {
228
- if (fieldModelBuilder . getFieldName ().equals (name )) {
229
- return fieldModelBuilder ;
224
+ public PropertyModelBuilder <?> getProperty (final String propertyName ) {
225
+ notNull ("propertyName " , propertyName );
226
+ for (PropertyModelBuilder <?> propertyModelBuilder : propertyModelBuilders ) {
227
+ if (propertyModelBuilder . getName ().equals (propertyName )) {
228
+ return propertyModelBuilder ;
230
229
}
231
230
}
232
231
return null ;
233
232
}
234
233
235
234
/**
236
- * @return the fields on the modeled type
235
+ * @return the properties on the modeled type
237
236
*/
238
- public List <FieldModelBuilder <?>> getFields () {
239
- return Collections .unmodifiableList (fields );
237
+ public List <PropertyModelBuilder <?>> getPropertyModelBuilders () {
238
+ return Collections .unmodifiableList (propertyModelBuilders );
240
239
}
241
240
242
241
/**
@@ -245,8 +244,8 @@ public List<FieldModelBuilder<?>> getFields() {
245
244
* @return the new instance
246
245
*/
247
246
public ClassModel <T > build () {
248
- List <FieldModel <?>> fieldModels = new ArrayList <FieldModel <?>>();
249
- FieldModel <?> idFieldModel = null ;
247
+ List <PropertyModel <?>> propertyModels = new ArrayList <PropertyModel <?>>();
248
+ PropertyModel <?> idPropertyModel = null ;
250
249
251
250
stateNotNull ("type" , type );
252
251
for (Convention convention : conventions ) {
@@ -259,72 +258,71 @@ public ClassModel<T> build() {
259
258
stateNotNull ("discriminator" , discriminator );
260
259
}
261
260
262
- for (FieldModelBuilder <?> fieldModelBuilder : fields ) {
263
- boolean isIdField = fieldModelBuilder . getFieldName ().equals (idField );
264
- if (isIdField ) {
265
- fieldModelBuilder . documentFieldName ( ID_FIELD_NAME );
261
+ for (PropertyModelBuilder <?> propertyModelBuilder : propertyModelBuilders ) {
262
+ boolean isIdProperty = propertyModelBuilder . getName ().equals (idPropertyName );
263
+ if (isIdProperty ) {
264
+ propertyModelBuilder . readName ( ID_PROPERTY_NAME ). writeName ( ID_PROPERTY_NAME );
266
265
}
267
266
268
- FieldModel <?> model = fieldModelBuilder .build ();
269
- fieldModels .add (model );
270
- if (isIdField ) {
271
- idFieldModel = model ;
267
+ PropertyModel <?> model = propertyModelBuilder .build ();
268
+ propertyModels .add (model );
269
+ if (isIdProperty ) {
270
+ idPropertyModel = model ;
272
271
}
273
272
}
274
- validateFieldModels ( fieldModels );
273
+ validatePropertyModels ( type . getSimpleName (), propertyModels );
275
274
276
275
277
- return new ClassModel <T >(type , fieldNameToTypeParameterMap , instanceCreatorFactory , discriminatorEnabled , discriminatorKey ,
278
- discriminator , idFieldModel , unmodifiableList (fieldModels ));
276
+ return new ClassModel <T >(type , propertyNameToTypeParameterMap , instanceCreatorFactory , discriminatorEnabled , discriminatorKey ,
277
+ discriminator , idPropertyModel , unmodifiableList (propertyModels ));
279
278
}
280
279
281
280
@ Override
282
281
public String toString () {
283
282
return format ("ClassModelBuilder{type=%s}" , type );
284
283
}
285
284
286
- Map <String , TypeParameterMap > getFieldNameToTypeParameterMap () {
287
- return fieldNameToTypeParameterMap ;
285
+ Map <String , TypeParameterMap > getPropertyNameToTypeParameterMap () {
286
+ return propertyNameToTypeParameterMap ;
288
287
}
289
288
290
- ClassModelBuilder <T > fieldNameToTypeParameterMap (final Map <String , TypeParameterMap > fieldNameToTypeParameterMap ) {
291
- this .fieldNameToTypeParameterMap = unmodifiableMap (new HashMap <String , TypeParameterMap >(fieldNameToTypeParameterMap ));
289
+ ClassModelBuilder <T > propertyNameToTypeParameterMap (final Map <String , TypeParameterMap > propertyNameToTypeParameterMap ) {
290
+ this .propertyNameToTypeParameterMap = unmodifiableMap (new HashMap <String , TypeParameterMap >(propertyNameToTypeParameterMap ));
292
291
return this ;
293
292
}
294
293
295
- ClassModelBuilder <T > addField (final FieldModelBuilder <?> fieldModelBuilder ) {
296
- fields .add (notNull ("fieldModelBuilder " , fieldModelBuilder ));
294
+ ClassModelBuilder <T > addProperty (final PropertyModelBuilder <?> propertyModelBuilder ) {
295
+ propertyModelBuilders .add (notNull ("propertyModelBuilder " , propertyModelBuilder ));
297
296
return this ;
298
297
}
299
298
300
- private void validateFieldModels (final List <FieldModel <?>> fieldModels ) {
301
- Map <String , Integer > fieldNameMap = new HashMap <String , Integer >();
302
- Map <String , Integer > fieldDocumentNameMap = new HashMap <String , Integer >();
303
- String duplicateFieldName = null ;
304
- String duplicateDocumentFieldName = null ;
305
-
306
- for (FieldModel <?> fieldModel : fieldModels ) {
307
- String fieldName = fieldModel .getFieldName ();
308
- if (fieldNameMap .containsKey (fieldName )) {
309
- duplicateFieldName = fieldName ;
310
- break ;
311
- }
312
- fieldNameMap .put (fieldName , 1 );
299
+ private void validatePropertyModels (final String declaringClass , final List <PropertyModel <?>> propertyModels ) {
300
+ Map <String , Integer > propertyNameMap = new HashMap <String , Integer >();
301
+ Map <String , Integer > propertyReadNameMap = new HashMap <String , Integer >();
302
+ Map <String , Integer > propertyWriteNameMap = new HashMap <String , Integer >();
313
303
314
- String documentFieldName = fieldModel .getDocumentFieldName ();
315
- if (fieldDocumentNameMap .containsKey (documentFieldName )) {
316
- duplicateDocumentFieldName = documentFieldName ;
317
- break ;
304
+ for (PropertyModel <?> propertyModel : propertyModels ) {
305
+ checkForDuplicates ("property" , propertyModel .getName (), propertyNameMap , declaringClass );
306
+ if (propertyModel .isReadable ()) {
307
+ checkForDuplicates ("read property" , propertyModel .getReadName (), propertyReadNameMap , declaringClass );
308
+ }
309
+ if (propertyModel .isWritable ()) {
310
+ checkForDuplicates ("write property" , propertyModel .getWriteName (), propertyWriteNameMap , declaringClass );
318
311
}
319
- fieldDocumentNameMap .put (documentFieldName , 1 );
320
312
}
321
- if (idField != null && !fieldNameMap .containsKey (idField )) {
322
- throw new IllegalStateException (format ("Invalid id field, field named field '%s' can not be found." , idField ));
323
- } else if (duplicateFieldName != null ) {
324
- throw new IllegalStateException (format ("Duplicate field named '%s' found." , duplicateFieldName ));
325
- } else if (duplicateDocumentFieldName != null ) {
326
- throw new IllegalStateException (format ("Duplicate document field named '%s' found." , duplicateDocumentFieldName ));
313
+
314
+ if (idPropertyName != null && !propertyNameMap .containsKey (idPropertyName )) {
315
+ throw new CodecConfigurationException (format ("Invalid id property, property named '%s' can not be found." , idPropertyName ));
316
+ }
317
+ }
318
+
319
+ private void checkForDuplicates (final String propertyType , final String propertyName , final Map <String , Integer > propertyNameMap ,
320
+ final String declaringClass ) {
321
+ if (propertyNameMap .containsKey (propertyName )) {
322
+ throw new CodecConfigurationException (format ("Duplicate %s named '%s' found in %s." , propertyType , propertyName ,
323
+ declaringClass ));
327
324
}
325
+ propertyNameMap .put (propertyName , 1 );
328
326
}
329
327
330
328
}
0 commit comments