1 | |
|
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
|
12 | |
|
13 | |
|
14 | |
|
15 | |
|
16 | |
package org.dozer.loader; |
17 | |
|
18 | |
import org.apache.commons.lang3.StringUtils; |
19 | |
import org.dozer.CustomConverter; |
20 | |
import org.dozer.MappingException; |
21 | |
import org.dozer.classmap.*; |
22 | |
import org.dozer.converters.CustomConverterDescription; |
23 | |
import org.dozer.fieldmap.*; |
24 | |
import org.dozer.util.DozerConstants; |
25 | |
import org.dozer.util.MappingUtils; |
26 | |
|
27 | |
import java.util.ArrayList; |
28 | |
import java.util.List; |
29 | |
|
30 | |
|
31 | |
|
32 | |
|
33 | |
|
34 | |
|
35 | |
|
36 | |
|
37 | |
|
38 | |
|
39 | |
|
40 | |
|
41 | 56130 | public class DozerBuilder { |
42 | |
|
43 | 630 | MappingFileData data = new MappingFileData(); |
44 | 630 | private final List<MappingBuilder> mappingBuilders = new ArrayList<MappingBuilder>(); |
45 | |
|
46 | |
public MappingFileData build() { |
47 | 626 | for (MappingBuilder builder : mappingBuilders) { |
48 | 5480 | builder.build(); |
49 | 5480 | } |
50 | 626 | return data; |
51 | |
} |
52 | |
|
53 | |
public ConfigurationBuilder configuration() { |
54 | 233 | Configuration configuration = new Configuration(); |
55 | 233 | data.setConfiguration(configuration); |
56 | 233 | return new ConfigurationBuilder(configuration); |
57 | |
} |
58 | |
|
59 | |
public MappingBuilder mapping() { |
60 | 5484 | Configuration configuration = data.getConfiguration(); |
61 | 5484 | ClassMap classMap = new ClassMap(configuration); |
62 | 5484 | data.getClassMaps().add(classMap); |
63 | 5484 | MappingBuilder mappingDefinitionBuilder = new MappingBuilder(classMap); |
64 | 5484 | mappingBuilders.add(mappingDefinitionBuilder); |
65 | 5484 | return mappingDefinitionBuilder; |
66 | |
} |
67 | |
|
68 | |
public static class MappingBuilder { |
69 | |
|
70 | |
private ClassMap classMap; |
71 | 5484 | private final List<FieldBuider> fieldBuilders = new ArrayList<FieldBuider>(); |
72 | |
|
73 | 5484 | public MappingBuilder(ClassMap classMap) { |
74 | 5484 | this.classMap = classMap; |
75 | 5484 | } |
76 | |
|
77 | |
public MappingBuilder dateFormat(String dateFormat) { |
78 | 110 | classMap.setDateFormat(dateFormat); |
79 | 110 | return this; |
80 | |
} |
81 | |
|
82 | |
public MappingBuilder mapNull(boolean value) { |
83 | 67 | classMap.setMapNull(value); |
84 | 67 | return this; |
85 | |
} |
86 | |
|
87 | |
public MappingBuilder mapEmptyString(boolean value) { |
88 | 15 | classMap.setMapEmptyString(value); |
89 | 15 | return this; |
90 | |
} |
91 | |
|
92 | |
|
93 | |
public MappingBuilder beanFactory(String typeName) { |
94 | 1 | classMap.setBeanFactory(typeName); |
95 | 1 | return this; |
96 | |
} |
97 | |
|
98 | |
public MappingBuilder relationshipType(RelationshipType type) { |
99 | 3 | classMap.setRelationshipType(type); |
100 | 3 | return this; |
101 | |
} |
102 | |
|
103 | |
public MappingBuilder wildcard(Boolean value) { |
104 | 871 | classMap.setWildcard(value); |
105 | 871 | return this; |
106 | |
} |
107 | |
|
108 | |
public MappingBuilder trimStrings(Boolean value) { |
109 | 7 | classMap.setTrimStrings(value); |
110 | 7 | return this; |
111 | |
} |
112 | |
|
113 | |
public MappingBuilder stopOnErrors(Boolean value) { |
114 | 444 | classMap.setStopOnErrors(value); |
115 | 444 | return this; |
116 | |
} |
117 | |
|
118 | |
public MappingBuilder mapId(String id) { |
119 | 677 | classMap.setMapId(id); |
120 | 677 | return this; |
121 | |
} |
122 | |
|
123 | |
public MappingBuilder type(MappingDirection type) { |
124 | 281 | classMap.setType(type); |
125 | 281 | return this; |
126 | |
} |
127 | |
|
128 | |
public ClassDefinitionBuilder classA(String typeName) { |
129 | 5484 | Class<?> type = MappingUtils.loadClass(typeName); |
130 | 5482 | return classA(type); |
131 | |
} |
132 | |
|
133 | |
public ClassDefinitionBuilder classA(Class type) { |
134 | 5482 | DozerClass classDefinition = new DozerClass(); |
135 | 5482 | classDefinition.setName(type.getName()); |
136 | 5482 | classMap.setSrcClass(classDefinition); |
137 | 5482 | return new ClassDefinitionBuilder(classDefinition); |
138 | |
} |
139 | |
|
140 | |
public ClassDefinitionBuilder classB(String typeName) { |
141 | 5482 | Class<?> type = MappingUtils.loadClass(typeName); |
142 | 5482 | return classB(type); |
143 | |
} |
144 | |
|
145 | |
public ClassDefinitionBuilder classB(Class type) { |
146 | 5482 | DozerClass classDefinition = new DozerClass(); |
147 | 5482 | classDefinition.setName(type.getName()); |
148 | 5482 | classMap.setDestClass(classDefinition); |
149 | 5482 | return new ClassDefinitionBuilder(classDefinition); |
150 | |
} |
151 | |
|
152 | |
public FieldExclusionBuilder fieldExclude() { |
153 | 829 | ExcludeFieldMap excludeFieldMap = new ExcludeFieldMap(classMap); |
154 | 829 | FieldExclusionBuilder builder = new FieldExclusionBuilder(excludeFieldMap); |
155 | 829 | fieldBuilders.add(builder); |
156 | 829 | return builder; |
157 | |
} |
158 | |
|
159 | |
public FieldMappingBuilder field() { |
160 | 13473 | FieldMappingBuilder builder = new FieldMappingBuilder(classMap); |
161 | 13473 | fieldBuilders.add(builder); |
162 | 13473 | return builder; |
163 | |
} |
164 | |
|
165 | |
public void build() { |
166 | 5480 | for (FieldBuider builder : fieldBuilders) { |
167 | 14300 | builder.build(); |
168 | 14300 | } |
169 | 5480 | } |
170 | |
|
171 | |
} |
172 | |
|
173 | |
public interface FieldBuider { |
174 | |
FieldDefinitionBuilder a(String name, String type); |
175 | |
|
176 | |
FieldDefinitionBuilder b(String name, String type); |
177 | |
|
178 | |
void build(); |
179 | |
} |
180 | |
|
181 | |
public static class FieldExclusionBuilder implements FieldBuider { |
182 | |
|
183 | |
private ExcludeFieldMap fieldMap; |
184 | |
|
185 | 829 | public FieldExclusionBuilder(ExcludeFieldMap fieldMap) { |
186 | 829 | this.fieldMap = fieldMap; |
187 | 829 | } |
188 | |
|
189 | |
public void type(MappingDirection type) { |
190 | 828 | fieldMap.setType(type); |
191 | 828 | } |
192 | |
|
193 | |
public FieldDefinitionBuilder a(String name, String type) { |
194 | 829 | DozerField field = prepareField(name, type); |
195 | 829 | fieldMap.setSrcField(field); |
196 | 829 | return new FieldDefinitionBuilder(field); |
197 | |
} |
198 | |
|
199 | |
public FieldDefinitionBuilder b(String name, String type) { |
200 | 829 | DozerField field = prepareField(name, type); |
201 | 829 | fieldMap.setDestField(field); |
202 | 829 | return new FieldDefinitionBuilder(field); |
203 | |
} |
204 | |
|
205 | |
|
206 | |
public void build() { |
207 | 829 | ClassMap classMap = fieldMap.getClassMap(); |
208 | 829 | classMap.addFieldMapping(fieldMap); |
209 | 829 | } |
210 | |
|
211 | |
} |
212 | |
|
213 | |
public static class FieldMappingBuilder implements FieldBuider { |
214 | |
|
215 | |
private ClassMap classMap; |
216 | |
private DozerField srcField; |
217 | |
private DozerField destField; |
218 | |
private MappingDirection type; |
219 | |
private RelationshipType relationshipType; |
220 | |
private boolean removeOrphans; |
221 | |
private HintContainer srcHintContainer; |
222 | |
private HintContainer destHintContainer; |
223 | |
private HintContainer srcDeepIndexHintContainer; |
224 | |
private HintContainer destDeepIndexHintContainer; |
225 | |
private boolean copyByReference; |
226 | |
private String mapId; |
227 | |
private String customConverter; |
228 | |
private String customConverterId; |
229 | |
private String customConverterParam; |
230 | |
private boolean copyByReferenceSet; |
231 | |
|
232 | 13473 | public FieldMappingBuilder(ClassMap classMap) { |
233 | 13473 | this.classMap = classMap; |
234 | 13473 | } |
235 | |
|
236 | |
public FieldDefinitionBuilder a(String name) { |
237 | 23 | return a(name, null); |
238 | |
} |
239 | |
|
240 | |
public FieldDefinitionBuilder a(String name, String type) { |
241 | 26921 | DozerField field = prepareField(name, type); |
242 | 26921 | this.srcField = field; |
243 | 26921 | return new FieldDefinitionBuilder(field); |
244 | |
} |
245 | |
|
246 | |
public FieldDefinitionBuilder b(String name) { |
247 | 23 | return b(name, null); |
248 | |
} |
249 | |
|
250 | |
public FieldDefinitionBuilder b(String name, String type) { |
251 | 26921 | DozerField field = prepareField(name, type); |
252 | 26919 | this.destField = field; |
253 | 26919 | return new FieldDefinitionBuilder(field); |
254 | |
} |
255 | |
|
256 | |
public void type(MappingDirection type) { |
257 | 563 | this.type = type; |
258 | 563 | } |
259 | |
|
260 | |
public void relationshipType(RelationshipType relationshipType) { |
261 | 13455 | this.relationshipType = relationshipType; |
262 | 13455 | } |
263 | |
|
264 | |
public void removeOrphans(boolean value) { |
265 | 29 | this.removeOrphans = value; |
266 | 29 | } |
267 | |
|
268 | |
public void srcHintContainer(String hint) { |
269 | 1817 | HintContainer hintContainer = new HintContainer(); |
270 | 1817 | hintContainer.setHintName(hint); |
271 | 1817 | this.srcHintContainer = hintContainer; |
272 | 1817 | } |
273 | |
|
274 | |
public void destHintContainer(String hint) { |
275 | 2586 | HintContainer hintContainer = new HintContainer(); |
276 | 2586 | hintContainer.setHintName(hint); |
277 | 2586 | this.destHintContainer = hintContainer; |
278 | 2586 | } |
279 | |
|
280 | |
public void srcDeepIndexHintContainer(String hint) { |
281 | 35 | HintContainer hintContainer = new HintContainer(); |
282 | 35 | hintContainer.setHintName(hint); |
283 | 35 | this.srcDeepIndexHintContainer = hintContainer; |
284 | 35 | } |
285 | |
|
286 | |
public void destDeepIndexHintContainer(String hint) { |
287 | 49 | HintContainer hintContainer = new HintContainer(); |
288 | 49 | hintContainer.setHintName(hint); |
289 | 49 | this.destDeepIndexHintContainer = hintContainer; |
290 | 49 | } |
291 | |
|
292 | |
public void copyByReference(boolean value) { |
293 | 230 | this.copyByReferenceSet = true; |
294 | 230 | this.copyByReference = value; |
295 | 230 | } |
296 | |
|
297 | |
public void mapId(String attribute) { |
298 | 577 | this.mapId = attribute; |
299 | 577 | } |
300 | |
|
301 | |
public void customConverter(Class<? extends CustomConverter> type) { |
302 | 0 | customConverter(type.getName()); |
303 | 0 | } |
304 | |
|
305 | |
public void customConverter(String typeName) { |
306 | 72 | this.customConverter = typeName; |
307 | 72 | } |
308 | |
|
309 | |
public void customConverterId(String attribute) { |
310 | 17 | this.customConverterId = attribute; |
311 | 17 | } |
312 | |
|
313 | |
public void customConverterParam(String attribute) { |
314 | 25 | this.customConverterParam = attribute; |
315 | 25 | } |
316 | |
|
317 | |
public void build() { |
318 | |
|
319 | |
FieldMap result; |
320 | 13471 | if (srcField.isMapTypeCustomGetterSetterField() || destField.isMapTypeCustomGetterSetterField() |
321 | |
|| classMap.isSrcClassMapTypeCustomGetterSetter() || classMap.isDestClassMapTypeCustomGetterSetter()) { |
322 | 720 | result = new MapFieldMap(classMap); |
323 | 12751 | } else if (srcField.isCustomGetterSetterField() || destField.isCustomGetterSetterField()) { |
324 | 1457 | result = new CustomGetSetMethodFieldMap(classMap); |
325 | |
} else { |
326 | 11294 | result = new GenericFieldMap(classMap); |
327 | |
} |
328 | |
|
329 | 13471 | result.setSrcField(srcField); |
330 | 13471 | result.setDestField(destField); |
331 | 13471 | result.setType(type); |
332 | 13471 | result.setRelationshipType(relationshipType); |
333 | 13471 | result.setRemoveOrphans(removeOrphans); |
334 | |
|
335 | 13471 | result.setSrcHintContainer(srcHintContainer); |
336 | 13471 | result.setDestHintContainer(destHintContainer); |
337 | 13471 | result.setSrcDeepIndexHintContainer(srcDeepIndexHintContainer); |
338 | 13471 | result.setDestDeepIndexHintContainer(destDeepIndexHintContainer); |
339 | |
|
340 | 13471 | if (copyByReferenceSet) { |
341 | 230 | result.setCopyByReference(copyByReference); |
342 | |
} |
343 | 13471 | result.setMapId(mapId); |
344 | |
|
345 | 13471 | result.setCustomConverter(customConverter); |
346 | 13471 | result.setCustomConverterId(customConverterId); |
347 | 13471 | result.setCustomConverterParam(customConverterParam); |
348 | |
|
349 | 13471 | classMap.addFieldMapping(result); |
350 | 13471 | } |
351 | |
|
352 | |
} |
353 | |
|
354 | |
public static class FieldDefinitionBuilder { |
355 | |
private DozerField field; |
356 | |
|
357 | 55498 | public FieldDefinitionBuilder(DozerField field) { |
358 | 55498 | this.field = field; |
359 | 55498 | } |
360 | |
|
361 | |
public void dateFormat(String attribute) { |
362 | 276 | field.setDateFormat(attribute); |
363 | 276 | } |
364 | |
|
365 | |
public void theGetMethod(String attribute) { |
366 | 710 | field.setTheGetMethod(attribute); |
367 | 710 | } |
368 | |
|
369 | |
public void theSetMethod(String attribute) { |
370 | 3618 | field.setTheSetMethod(attribute); |
371 | 3618 | } |
372 | |
|
373 | |
public void mapGetMethod(String attribute) { |
374 | 1002 | field.setMapGetMethod(attribute); |
375 | 1002 | } |
376 | |
|
377 | |
public void mapSetMethod(String attribute) { |
378 | 982 | field.setMapSetMethod(attribute); |
379 | 982 | } |
380 | |
|
381 | |
public void key(String attribute) { |
382 | 1830 | field.setKey(attribute); |
383 | 1830 | } |
384 | |
|
385 | |
public void createMethod(String attribute) { |
386 | 86 | field.setCreateMethod(attribute); |
387 | 86 | } |
388 | |
|
389 | |
public void accessible(Boolean b) { |
390 | 274 | field.setAccessible(b); |
391 | 274 | } |
392 | |
|
393 | |
public void iterate() { |
394 | 1 | field.setType(DozerConstants.ITERATE); |
395 | 1 | } |
396 | |
|
397 | |
public DozerField build() { |
398 | 0 | return field; |
399 | |
} |
400 | |
|
401 | |
} |
402 | |
|
403 | |
private static DozerField prepareField(String name, String type) { |
404 | 55500 | if (MappingUtils.isBlankOrNull(name)) { |
405 | 2 | throw new MappingException("Field name can not be empty"); |
406 | |
} |
407 | |
String fieldName; |
408 | 55498 | String fieldType = null; |
409 | 55498 | if (isIndexed(name)) { |
410 | 432 | fieldName = getFieldNameOfIndexedField(name); |
411 | |
} else { |
412 | 55066 | fieldName = name; |
413 | |
} |
414 | 55498 | if (StringUtils.isNotEmpty(type)) { |
415 | 1348 | fieldType = type; |
416 | |
} |
417 | 55498 | DozerField field = new DozerField(fieldName, fieldType); |
418 | 55498 | if (isIndexed(name)) { |
419 | 432 | field.setIndexed(true); |
420 | 432 | field.setIndex(getIndexOfIndexedField(name)); |
421 | |
} |
422 | 55498 | return field; |
423 | |
} |
424 | |
|
425 | |
|
426 | |
private static boolean isIndexed(String fieldName) { |
427 | 110996 | return (fieldName != null) && (fieldName.matches(".+\\[\\d+\\]")); |
428 | |
} |
429 | |
|
430 | |
static String getFieldNameOfIndexedField(String fieldName) { |
431 | 435 | return fieldName == null ? null : fieldName.replaceAll("\\[\\d+\\]$", ""); |
432 | |
} |
433 | |
|
434 | |
private static int getIndexOfIndexedField(String fieldName) { |
435 | 432 | return Integer.parseInt(fieldName.replaceAll(".*\\[", "").replaceAll("\\]", "")); |
436 | |
} |
437 | |
|
438 | |
public static class ClassDefinitionBuilder { |
439 | |
|
440 | |
private DozerClass definition; |
441 | |
|
442 | 10964 | public ClassDefinitionBuilder(DozerClass definition) { |
443 | 10964 | this.definition = definition; |
444 | 10964 | } |
445 | |
|
446 | |
public void mapGetMethod(String name) { |
447 | 282 | definition.setMapGetMethod(name); |
448 | 282 | } |
449 | |
|
450 | |
public void mapSetMethod(String name) { |
451 | 282 | definition.setMapSetMethod(name); |
452 | 282 | } |
453 | |
|
454 | |
public void beanFactory(String beanFactory) { |
455 | 124 | definition.setBeanFactory(beanFactory); |
456 | 124 | } |
457 | |
|
458 | |
public void factoryBeanId(String id) { |
459 | 59 | definition.setFactoryBeanId(id); |
460 | 59 | } |
461 | |
|
462 | |
public void createMethod(String name) { |
463 | 68 | definition.setCreateMethod(name); |
464 | 68 | } |
465 | |
|
466 | |
public void mapNull(Boolean value) { |
467 | 70 | definition.setMapNull(value); |
468 | 70 | } |
469 | |
|
470 | |
public void mapEmptyString(Boolean value) { |
471 | 70 | definition.setMapEmptyString(value); |
472 | 70 | } |
473 | |
|
474 | |
public void isAccessible(Boolean value) { |
475 | 82 | definition.setAccessible(value); |
476 | 82 | } |
477 | |
} |
478 | |
|
479 | |
public static class ConfigurationBuilder { |
480 | |
|
481 | |
private Configuration configuration; |
482 | |
|
483 | |
private CustomConverterDescription converterDescription; |
484 | |
|
485 | 233 | public ConfigurationBuilder(Configuration configuration) { |
486 | 233 | this.configuration = configuration; |
487 | 233 | } |
488 | |
|
489 | |
public void stopOnErrors(Boolean value) { |
490 | 144 | configuration.setStopOnErrors(value); |
491 | 144 | } |
492 | |
|
493 | |
public void dateFormat(String format) { |
494 | 135 | configuration.setDateFormat(format); |
495 | 135 | } |
496 | |
|
497 | |
public void wildcard(Boolean value) { |
498 | 138 | configuration.setWildcard(value); |
499 | 138 | } |
500 | |
|
501 | |
public void trimStrings(Boolean value) { |
502 | 6 | configuration.setTrimStrings(value); |
503 | 6 | } |
504 | |
|
505 | |
public void mapNull(Boolean value) { |
506 | 1 | configuration.setMapNull(value); |
507 | 1 | } |
508 | |
|
509 | |
public void mapEmptyString(Boolean value) { |
510 | 1 | configuration.setMapEmptyString(value); |
511 | 1 | } |
512 | |
|
513 | |
public void relationshipType(RelationshipType value) { |
514 | 2 | if (value == null) { |
515 | 0 | configuration.setRelationshipType(DozerConstants.DEFAULT_RELATIONSHIP_TYPE_POLICY); |
516 | |
} else { |
517 | 2 | configuration.setRelationshipType(value); |
518 | |
} |
519 | 2 | } |
520 | |
|
521 | |
public void beanFactory(String name) { |
522 | 5 | configuration.setBeanFactory(name); |
523 | 5 | } |
524 | |
|
525 | |
public CustomConverterBuilder customConverter(String type) { |
526 | 395 | Class<?> aClass = MappingUtils.loadClass(type); |
527 | 395 | return customConverter(aClass); |
528 | |
} |
529 | |
|
530 | |
|
531 | |
public CustomConverterBuilder customConverter(Class type) { |
532 | 395 | converterDescription = new CustomConverterDescription(); |
533 | 395 | converterDescription.setType(type); |
534 | 395 | configuration.getCustomConverters().addConverter(converterDescription); |
535 | 395 | return new CustomConverterBuilder(converterDescription); |
536 | |
} |
537 | |
|
538 | |
public ConfigurationBuilder copyByReference(String typeMask) { |
539 | 130 | CopyByReference copyByReference = new CopyByReference(typeMask); |
540 | 130 | configuration.getCopyByReferences().add(copyByReference); |
541 | 130 | return this; |
542 | |
} |
543 | |
|
544 | |
public ConfigurationBuilder allowedException(String type) { |
545 | 4 | Class<?> exceptionType = MappingUtils.loadClass(type); |
546 | 4 | return allowedException(exceptionType); |
547 | |
} |
548 | |
|
549 | |
|
550 | |
public ConfigurationBuilder allowedException(Class type) { |
551 | 4 | if (!RuntimeException.class.isAssignableFrom(type)) { |
552 | 0 | MappingUtils.throwMappingException("allowed-exception Type must extend java.lang.RuntimeException: " |
553 | |
+ type.getName()); |
554 | |
} |
555 | 4 | configuration.getAllowedExceptions().getExceptions().add(type); |
556 | 4 | return this; |
557 | |
} |
558 | |
|
559 | |
} |
560 | |
|
561 | 630 | public static class CustomConverterBuilder { |
562 | |
private CustomConverterDescription converterDescription; |
563 | |
|
564 | 395 | public CustomConverterBuilder(CustomConverterDescription converterDescription) { |
565 | 395 | this.converterDescription = converterDescription; |
566 | 395 | } |
567 | |
|
568 | |
public CustomConverterBuilder classA(String type) { |
569 | 395 | Class<?> aClass = MappingUtils.loadClass(type); |
570 | 395 | return classA(aClass); |
571 | |
} |
572 | |
|
573 | |
public CustomConverterBuilder classA(Class type) { |
574 | 395 | converterDescription.setClassA(type); |
575 | 395 | return this; |
576 | |
} |
577 | |
|
578 | |
public CustomConverterBuilder classB(String type) { |
579 | 395 | Class<?> aClass = MappingUtils.loadClass(type); |
580 | 395 | return classB(aClass); |
581 | |
} |
582 | |
|
583 | |
public CustomConverterBuilder classB(Class type) { |
584 | 395 | converterDescription.setClassB(type); |
585 | 395 | return this; |
586 | |
} |
587 | |
|
588 | |
} |
589 | |
|
590 | |
} |