1
16 package org.modelmapper.internal.converter;
17
18 import java.lang.reflect.Array;
19 import java.lang.reflect.GenericArrayType;
20 import java.util.Collection;
21
22 import java.util.Iterator;
23 import org.modelmapper.internal.util.Iterables;
24 import org.modelmapper.internal.util.Types;
25 import org.modelmapper.spi.ConditionalConverter;
26 import org.modelmapper.spi.MappingContext;
27
28
33 class ArrayConverter implements ConditionalConverter<Object, Object> {
34 @Override
35 public MatchResult match(Class<?> sourceType, Class<?> destinationType) {
36 return Iterables.isIterable(sourceType) && destinationType.isArray() ? MatchResult.FULL
37 : MatchResult.NONE;
38 }
39
40 @Override
41 public Object convert(MappingContext<Object, Object> context) {
42 Object source = context.getSource();
43 if (source == null)
44 return null;
45
46 boolean destinationProvided = context.getDestination() != null;
47 Object destination = createDestination(context);
48
49 Class<?> elementType = getElementType(context);
50 int index = 0;
51 for (Iterator<Object> iterator = Iterables.iterator(source); iterator.hasNext(); index++) {
52 Object sourceElement = iterator.next();
53 Object element = null;
54 if (destinationProvided)
55 element = Iterables.getElement(destination, index);
56 if (sourceElement != null) {
57 MappingContext<?, ?> elementContext = element == null
58 ? context.create(sourceElement, elementType)
59 : context.create(sourceElement, element);
60 element = context.getMappingEngine().map(elementContext);
61 }
62 Array.set(destination, index, element);
63 }
64
65 return destination;
66 }
67
68 @SuppressWarnings("all")
69 private Object createDestination(MappingContext<Object, Object> context) {
70 int sourceLength = Iterables.getLength(context.getSource());
71 int destinationLength = context.getDestination() != null ? Iterables.getLength(context.getDestination()) : 0;
72 int newLength = Math.max(sourceLength, destinationLength);
73 Object originalDestination = context.getDestination();
74
75 Class<?> destType = context.getDestinationType();
76 Object destination = Array.newInstance(destType.isArray() ? destType.getComponentType() : destType, newLength);
77 if (originalDestination != null)
78 System.arraycopy(originalDestination, 0, destination, 0, destinationLength);
79 return destination;
80 }
81
82 private Class<?> getElementType(MappingContext<Object, Object> context) {
83 if (context.getGenericDestinationType() instanceof GenericArrayType)
84 return Types.rawTypeFor(context.getGenericDestinationType())
85 .getComponentType();
86 return context.getDestinationType().getComponentType();
87 }
88 }
89