1
16 package org.modelmapper.internal.converter;
17
18 import java.lang.reflect.ParameterizedType;
19 import java.lang.reflect.Type;
20 import java.util.HashMap;
21 import java.util.Map;
22 import java.util.Map.Entry;
23 import java.util.SortedMap;
24 import java.util.TreeMap;
25
26 import net.jodah.typetools.TypeResolver;
27 import net.jodah.typetools.TypeResolver.Unknown;
28
29 import org.modelmapper.spi.ConditionalConverter;
30 import org.modelmapper.spi.Mapping;
31 import org.modelmapper.spi.MappingContext;
32 import org.modelmapper.spi.PropertyInfo;
33 import org.modelmapper.spi.PropertyMapping;
34
35
40 class MapConverter implements ConditionalConverter<Map<?, ?>, Map<Object, Object>> {
41 public Map<Object, Object> convert(MappingContext<Map<?, ?>, Map<Object, Object>> context) {
42 Map<?, ?> source = context.getSource();
43 if (source == null)
44 return null;
45
46 Map<Object, Object> destination = context.getDestination() == null ? createDestination(context)
47 : context.getDestination();
48 Mapping mapping = context.getMapping();
49
50 Type keyElementType = Object.class;
51 Type valueElementType = Object.class;
52 if (mapping instanceof PropertyMapping) {
53 PropertyInfo destInfo = mapping.getLastDestinationProperty();
54 Class<?>[] elementTypes = TypeResolver.resolveRawArguments(destInfo.getGenericType(),
55 Map.class);
56 if (elementTypes != null && elementTypes.length == 2) {
57 keyElementType = elementTypes[0] == Unknown.class ? Object.class : elementTypes[0];
58 valueElementType = elementTypes[1] == Unknown.class ? Object.class : elementTypes[1];
59 }
60 } else if (context.getGenericDestinationType() instanceof ParameterizedType) {
61 Type[] elementTypes = ((ParameterizedType) context.getGenericDestinationType()).getActualTypeArguments();
62 keyElementType = elementTypes[0];
63 valueElementType = elementTypes[1];
64 }
65
66 for (Entry<?, ?> entry : source.entrySet()) {
67 Object key = null;
68 if (entry.getKey() != null) {
69 MappingContext<?, ?> keyContext = context.create(entry.getKey(), keyElementType);
70 key = context.getMappingEngine().map(keyContext);
71 }
72
73 Object value = null;
74 if (entry.getValue() != null) {
75 MappingContext<?, ?> valueContext = context.create(entry.getValue(), valueElementType);
76 value = context.getMappingEngine().map(valueContext);
77 }
78
79 destination.put(key, value);
80 }
81
82 return destination;
83 }
84
85 public MatchResult match(Class<?> sourceType, Class<?> destinationType) {
86 return Map.class.isAssignableFrom(sourceType) && Map.class.isAssignableFrom(destinationType) ? MatchResult.FULL
87 : MatchResult.NONE;
88 }
89
90 protected Map<Object, Object> createDestination(
91 MappingContext<Map<?, ?>, Map<Object, Object>> context) {
92 if (!context.getDestinationType().isInterface())
93 return context.getMappingEngine().createDestination(context);
94 if (SortedMap.class.isAssignableFrom(context.getDestinationType()))
95 return new TreeMap<Object, Object>();
96 return new HashMap<Object, Object>();
97 }
98 }
99