0
# Programmatic Mapping API
1
2
Fluent Java API for defining mappings programmatically without XML configuration files, providing type-safe mapping definitions and advanced field mapping options.
3
4
## Capabilities
5
6
### Bean Mapping Builder Base Class
7
8
Abstract base class for creating programmatic mapping configurations.
9
10
```java { .api }
11
/**
12
* Programmatic builder of Dozer mappings using fluent API
13
*/
14
public abstract class BeanMappingBuilder {
15
/**
16
* Override this method to define your mappings using the fluent API
17
*/
18
public abstract void configure();
19
20
/**
21
* Creates a mapping between two classes
22
* @param typeA source class
23
* @param typeB destination class
24
* @param options mapping options (optional)
25
* @return TypeMappingBuilder for further configuration
26
*/
27
protected TypeMappingBuilder mapping(Class<?> typeA, Class<?> typeB, TypeMappingOption... options);
28
29
/**
30
* Creates a mapping between two classes by name
31
* @param typeA source class name
32
* @param typeB destination class name
33
* @param options mapping options (optional)
34
* @return TypeMappingBuilder for further configuration
35
*/
36
protected TypeMappingBuilder mapping(String typeA, String typeB, TypeMappingOption... options);
37
38
/**
39
* Creates a type definition for complex type configurations
40
* @param type the class type
41
* @return TypeDefinition for further configuration
42
*/
43
protected TypeDefinition type(Class<?> type);
44
45
/**
46
* Creates a field definition for field mapping
47
* @param name field name
48
* @return FieldDefinition for further configuration
49
*/
50
protected FieldDefinition field(String name);
51
52
/**
53
* References the current object being mapped (useful for self-mapping)
54
* @return FieldDefinition representing the current object
55
*/
56
protected FieldDefinition this_();
57
}
58
```
59
60
**Usage Example:**
61
62
```java
63
import com.github.dozermapper.core.loader.api.BeanMappingBuilder;
64
import com.github.dozermapper.core.loader.api.FieldsMappingOptions;
65
66
public class MyMappingsBuilder extends BeanMappingBuilder {
67
@Override
68
public void configure() {
69
// Basic class mapping
70
mapping(Person.class, PersonDto.class);
71
72
// Mapping with field customizations
73
mapping(User.class, UserDto.class)
74
.fields("firstName", "fname")
75
.fields("lastName", "lname")
76
.fields("birthDate", "dateOfBirth",
77
FieldsMappingOptions.customConverter(DateToStringConverter.class));
78
79
// Exclude specific fields
80
mapping(Product.class, ProductDto.class)
81
.exclude("internalId");
82
}
83
}
84
```
85
86
### Type Mapping Builder Interface
87
88
Interface for configuring class-level mapping options.
89
90
```java { .api }
91
/**
92
* Interface for configuring class-to-class mapping options
93
*/
94
public interface TypeMappingBuilder {
95
/**
96
* Maps fields between source and destination
97
* @param sourceField source field name
98
* @param destinationField destination field name
99
* @return TypeMappingBuilder for method chaining
100
*/
101
TypeMappingBuilder fields(String sourceField, String destinationField);
102
103
/**
104
* Maps fields with additional options
105
* @param sourceField source field name
106
* @param destinationField destination field name
107
* @param options field mapping options
108
* @return TypeMappingBuilder for method chaining
109
*/
110
TypeMappingBuilder fields(String sourceField, String destinationField, FieldsMappingOptions... options);
111
112
/**
113
* Maps field using FieldDefinition objects
114
* @param sourceField source field definition
115
* @param destinationField destination field definition
116
* @param options field mapping options
117
* @return TypeMappingBuilder for method chaining
118
*/
119
TypeMappingBuilder fields(FieldDefinition sourceField, FieldDefinition destinationField, FieldsMappingOptions... options);
120
121
/**
122
* Excludes a field from mapping
123
* @param fieldName field name to exclude
124
* @return TypeMappingBuilder for method chaining
125
*/
126
TypeMappingBuilder exclude(String fieldName);
127
}
128
```
129
130
### Field Definition Interface
131
132
Interface for defining complex field references and transformations.
133
134
```java { .api }
135
/**
136
* Interface for defining field references and transformations
137
*/
138
public interface FieldDefinition {
139
/**
140
* Accesses a nested field
141
* @param fieldName nested field name
142
* @return FieldDefinition for the nested field
143
*/
144
FieldDefinition field(String fieldName);
145
146
/**
147
* Accesses an indexed element (for arrays/collections)
148
* @param index array/collection index
149
* @return FieldDefinition for the indexed element
150
*/
151
FieldDefinition index(int index);
152
153
/**
154
* Accesses a map key
155
* @param key map key
156
* @return FieldDefinition for the map value
157
*/
158
FieldDefinition mapKey(Object key);
159
160
/**
161
* References the current object being mapped
162
* @return FieldDefinition representing the current object
163
*/
164
FieldDefinition this_();
165
}
166
```
167
168
### Type Definition Interface
169
170
Interface for configuring type-specific options.
171
172
```java { .api }
173
/**
174
* Interface for configuring type-specific options
175
*/
176
public interface TypeDefinition {
177
/**
178
* Sets the bean factory for this type
179
* @param beanFactory factory class
180
* @return TypeDefinition for method chaining
181
*/
182
TypeDefinition beanFactory(Class<? extends BeanFactory> beanFactory);
183
184
/**
185
* Sets the bean factory by name
186
* @param factoryName factory name
187
* @return TypeDefinition for method chaining
188
*/
189
TypeDefinition beanFactory(String factoryName);
190
191
/**
192
* Sets creation strategy for this type
193
* @param creationStrategy creation strategy
194
* @return TypeDefinition for method chaining
195
*/
196
TypeDefinition createMethod(String creationStrategy);
197
198
/**
199
* Sets map ID for this type
200
* @param mapId map identifier
201
* @return TypeDefinition for method chaining
202
*/
203
TypeDefinition mapId(String mapId);
204
}
205
```
206
207
## Field Mapping Options
208
209
### Basic Field Options
210
211
```java { .api }
212
/**
213
* Options for configuring field mappings
214
*/
215
public class FieldsMappingOptions {
216
/**
217
* Uses a custom converter for the field mapping
218
* @param converterClass converter class
219
* @return field mapping option
220
*/
221
public static FieldsMappingOption customConverter(Class<? extends CustomConverter> converterClass);
222
223
/**
224
* Uses a custom converter with ID for the field mapping
225
* @param converterId converter ID
226
* @return field mapping option
227
*/
228
public static FieldsMappingOption customConverterId(String converterId);
229
230
/**
231
* Copies the field by reference instead of deep copying
232
* @return field mapping option
233
*/
234
public static FieldsMappingOption copyByReference();
235
236
/**
237
* Uses a specific date format for date field conversions
238
* @param format date format string
239
* @return field mapping option
240
*/
241
public static FieldsMappingOption dateFormat(String format);
242
243
/**
244
* Uses conditional mapping based on source field value
245
* @param condition condition expression
246
* @return field mapping option
247
*/
248
public static FieldsMappingOption condition(String condition);
249
}
250
```
251
252
## Complete Mapping Examples
253
254
### Basic Entity to DTO Mapping
255
256
```java
257
public class PersonMappingsBuilder extends BeanMappingBuilder {
258
@Override
259
public void configure() {
260
mapping(Person.class, PersonDto.class)
261
.fields("firstName", "fname")
262
.fields("lastName", "lname")
263
.fields("dateOfBirth", "birthDate",
264
FieldsMappingOptions.dateFormat("yyyy-MM-dd"));
265
}
266
}
267
```
268
269
### Complex Nested Object Mapping
270
271
```java
272
public class OrderMappingsBuilder extends BeanMappingBuilder {
273
@Override
274
public void configure() {
275
mapping(Order.class, OrderDto.class)
276
.fields("customer.firstName", "customerName")
277
.fields("orderItems[0].product.name", "firstProductName")
278
.fields("shippingAddress", "deliveryAddress")
279
.exclude("internalNotes");
280
281
mapping(Customer.class, CustomerDto.class)
282
.fields("address.street", "streetAddress")
283
.fields("address.city", "cityName");
284
}
285
}
286
```
287
288
### Collection and Map Mapping
289
290
```java
291
public class CollectionMappingsBuilder extends BeanMappingBuilder {
292
@Override
293
public void configure() {
294
mapping(ProductCatalog.class, CatalogDto.class)
295
.fields("products", "productList")
296
.fields("categoryMap", "categories");
297
298
// Configure element mapping for collections
299
mapping(Product.class, ProductDto.class)
300
.fields("tags[0]", "primaryTag")
301
.fields("attributes", "attributeMap");
302
}
303
}
304
```
305
306
### Bidirectional Mapping
307
308
```java
309
public class BidirectionalMappingsBuilder extends BeanMappingBuilder {
310
@Override
311
public void configure() {
312
mapping(User.class, UserDto.class, TypeMappingOptions.mapId("user-to-dto"))
313
.fields("profile.displayName", "userName")
314
.fields("settings.theme", "preferredTheme");
315
316
mapping(UserDto.class, User.class, TypeMappingOptions.mapId("dto-to-user"))
317
.fields("userName", "profile.displayName")
318
.fields("preferredTheme", "settings.theme");
319
}
320
}
321
```
322
323
### Custom Converter Integration
324
325
```java
326
public class ConverterMappingsBuilder extends BeanMappingBuilder {
327
@Override
328
public void configure() {
329
mapping(Transaction.class, TransactionDto.class)
330
.fields("amount", "amountString",
331
FieldsMappingOptions.customConverter(MoneyToStringConverter.class))
332
.fields("timestamp", "dateTime",
333
FieldsMappingOptions.customConverter(TimestampConverter.class))
334
.fields("status", "statusCode",
335
FieldsMappingOptions.customConverterId("status-converter"));
336
}
337
}
338
```
339
340
## Registration with Mapper Builder
341
342
```java
343
import com.github.dozermapper.core.Mapper;
344
import com.github.dozermapper.core.DozerBeanMapperBuilder;
345
346
// Register programmatic mappings
347
Mapper mapper = DozerBeanMapperBuilder.create()
348
.withMappingBuilder(new PersonMappingsBuilder())
349
.withMappingBuilder(new OrderMappingsBuilder())
350
.withMappingBuilder(new CollectionMappingsBuilder())
351
.build();
352
```
353
354
## Advanced Features
355
356
### Conditional Mapping
357
358
```java
359
public class ConditionalMappingsBuilder extends BeanMappingBuilder {
360
@Override
361
public void configure() {
362
mapping(Employee.class, EmployeeDto.class)
363
.fields("salary", "salaryAmount",
364
FieldsMappingOptions.condition("salary != null && salary > 0"))
365
.fields("bonus", "bonusAmount",
366
FieldsMappingOptions.condition("isEligibleForBonus == true"));
367
}
368
}
369
```
370
371
### Copy by Reference
372
373
```java
374
public class ReferenceMappingsBuilder extends BeanMappingBuilder {
375
@Override
376
public void configure() {
377
mapping(Document.class, DocumentDto.class)
378
.fields("metadata", "metadata",
379
FieldsMappingOptions.copyByReference())
380
.fields("content", "documentContent");
381
}
382
}
383
```
384
385
### Deep Field Access
386
387
```java
388
public class DeepFieldMappingsBuilder extends BeanMappingBuilder {
389
@Override
390
public void configure() {
391
mapping(Invoice.class, InvoiceDto.class)
392
.fields(field("customer").field("company").field("address").field("zipCode"),
393
field("customerZip"))
394
.fields(field("lineItems").index(0).field("product").field("sku"),
395
field("firstItemSku"));
396
}
397
}
398
```
399
400
## Best Practices
401
402
### Organization
403
- Group related mappings in the same builder class
404
- Use descriptive class names for mapping builders
405
- Separate complex mappings into multiple builders
406
407
### Performance
408
- Prefer programmatic mappings over XML for better performance
409
- Register all builders during mapper creation, not at runtime
410
- Use map IDs for bidirectional mappings to avoid conflicts
411
412
### Maintainability
413
- Document complex field mappings with comments
414
- Use constants for field names when possible
415
- Test programmatic mappings thoroughly with unit tests
416
417
## Supporting Types
418
419
### Type Mapping Option Interface
420
421
Base interface for type-level mapping configuration options.
422
423
```java { .api }
424
/**
425
* Interface for type mapping configuration options
426
*/
427
public interface TypeMappingOption {
428
/**
429
* Applies this option to the mapping builder
430
* @param fieldMappingBuilder the mapping builder to configure
431
*/
432
void apply(DozerBuilder.MappingBuilder fieldMappingBuilder);
433
}
434
```
435
436
### Type Mapping Options Utility
437
438
Factory class for creating type mapping options.
439
440
```java { .api }
441
/**
442
* Utility class for creating type mapping options
443
*/
444
public final class TypeMappingOptions {
445
/**
446
* Sets a map ID for the mapping
447
* @param mapId unique identifier for this mapping
448
* @return TypeMappingOption for map ID
449
*/
450
public static TypeMappingOption mapId(String mapId);
451
452
/**
453
* Sets bidirectional mapping
454
* @return TypeMappingOption for bidirectional mapping
455
*/
456
public static TypeMappingOption oneWay();
457
458
/**
459
* Configures mapping direction
460
* @return TypeMappingOption for mapping direction
461
*/
462
public static TypeMappingOption mapNull(boolean mapNull);
463
464
/**
465
* Configures empty string mapping
466
* @return TypeMappingOption for empty string handling
467
*/
468
public static TypeMappingOption mapEmptyString(boolean mapEmptyString);
469
}
470
```
471
472
### Fields Mapping Options Utility
473
474
Factory class for creating field-level mapping options.
475
476
```java { .api }
477
/**
478
* Utility class for creating field mapping options
479
*/
480
public final class FieldsMappingOptions {
481
/**
482
* Sets a custom converter for the field
483
* @param converterClass converter class
484
* @return FieldsMappingOption for custom converter
485
*/
486
public static FieldsMappingOption customConverter(Class<? extends CustomConverter> converterClass);
487
488
/**
489
* Sets a custom converter by ID
490
* @param converterId converter identifier
491
* @return FieldsMappingOption for custom converter ID
492
*/
493
public static FieldsMappingOption customConverterId(String converterId);
494
495
/**
496
* Configures copy by reference
497
* @return FieldsMappingOption for copy by reference
498
*/
499
public static FieldsMappingOption copyByReference();
500
501
/**
502
* Sets a condition for field mapping
503
* @param condition mapping condition expression
504
* @return FieldsMappingOption for conditional mapping
505
*/
506
public static FieldsMappingOption condition(String condition);
507
508
/**
509
* Sets the mapping direction for this field
510
* @return FieldsMappingOption for one-way mapping
511
*/
512
public static FieldsMappingOption oneWay();
513
}
514
```