Skip to content

Commit 16cb53b

Browse files
committed
Merge branch 'master' into sebastiencaille-master
2 parents c03212a + 7203bfe commit 16cb53b

File tree

4 files changed

+135
-1
lines changed

4 files changed

+135
-1
lines changed

core/src/main/java/org/dozer/MappingProcessor.java

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import org.slf4j.LoggerFactory;
4040

4141
import java.lang.reflect.Array;
42+
import java.lang.reflect.Modifier;
4243
import java.lang.reflect.InvocationTargetException;
4344
import java.util.*;
4445
import java.util.Map.Entry;
@@ -613,8 +614,18 @@ private Object mapMap(Object srcObj, Map srcMapValue, FieldMap fieldMap, Object
613614

614615
private Object mapArrayToArray(Object srcObj, Object srcCollectionValue, FieldMap fieldMap, Object destObj) {
615616
Class destEntryType = fieldMap.getDestFieldType(destObj.getClass()).getComponentType();
617+
Class srcEntryType = srcCollectionValue.getClass().getComponentType();
616618
int size = Array.getLength(srcCollectionValue);
617-
if (CollectionUtils.isPrimitiveArray(srcCollectionValue.getClass())) {
619+
620+
CopyByReferenceContainer copyByReferences = globalConfiguration.getCopyByReferences();
621+
boolean isPrimitiveArray = CollectionUtils.isPrimitiveArray(srcCollectionValue.getClass());
622+
boolean isFinal = Modifier.isFinal(srcEntryType.getModifiers());
623+
boolean isCopyByReference = copyByReferences.contains(srcEntryType);
624+
625+
// TODO: what about custom converters?
626+
if (destEntryType.isAssignableFrom(srcEntryType) && isFinal && (isPrimitiveArray || isCopyByReference)) {
627+
return addArrayContentCopy(fieldMap, size, srcCollectionValue, destObj, destEntryType);
628+
} else if (isPrimitiveArray) {
618629
return addToPrimitiveArray(srcObj, fieldMap, size, srcCollectionValue, destObj, destEntryType);
619630
} else {
620631
List<?> list = Arrays.asList((Object[]) srcCollectionValue);
@@ -659,6 +670,22 @@ private void mapFromIterateMethodFieldMap(Object srcObj, Object destObj, Object
659670
fieldMapping.getDestFieldName(), srcFieldValue, null, fieldMapping.getClassMap().getMapId()));
660671
}
661672
}
673+
674+
private Object addArrayContentCopy(FieldMap fieldMap, int size, Object srcCollectionValue, Object destObj,
675+
Class destEntryType) {
676+
Object result;
677+
Object field = fieldMap.getDestValue(destObj);
678+
int arraySize = 0;
679+
if (field == null) {
680+
result = Array.newInstance(destEntryType, size);
681+
} else {
682+
result = Array.newInstance(destEntryType, size + Array.getLength(field));
683+
arraySize = Array.getLength(field);
684+
System.arraycopy(field, 0, result, 0, arraySize);
685+
}
686+
System.arraycopy(srcCollectionValue, 0, result, arraySize, size);
687+
return result;
688+
}
662689

663690
private Object addToPrimitiveArray(Object srcObj, FieldMap fieldMap, int size, Object srcCollectionValue, Object destObj,
664691
Class<?> destEntryType) {
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package org.dozer;
2+
3+
import java.util.Arrays;
4+
import java.util.Date;
5+
6+
public class MappingProcessorArrayTest extends AbstractDozerTest {
7+
8+
public static class PrimitiveArray {
9+
private int[] data;
10+
11+
public int[] getData() {
12+
return data;
13+
}
14+
15+
public void setData(int[] data) {
16+
this.data = data;
17+
}
18+
}
19+
20+
public static final class MyDate extends Date {
21+
public MyDate(long ms) {
22+
super(ms);
23+
}
24+
}
25+
26+
public static class FinalCopyByReferenceArray {
27+
private MyDate[] data;
28+
29+
public MyDate[] getData() {
30+
return data;
31+
}
32+
33+
public void setData(MyDate[] data) {
34+
this.data = data;
35+
}
36+
}
37+
38+
public static class FinalCopyByReferenceDest {
39+
private Date[] data;
40+
41+
public Date[] getData() {
42+
return data;
43+
}
44+
45+
public void setData(Date[] data) {
46+
this.data = data;
47+
}
48+
}
49+
50+
public void testPrimitiveArrayCopy() {
51+
52+
PrimitiveArray test = new PrimitiveArray();
53+
int[] data = new int[1024 * 1024];
54+
for (int i = 0; i < data.length; i++) {
55+
data[i] = i;
56+
}
57+
test.setData(data);
58+
DozerBeanMapper dozer = new DozerBeanMapper();
59+
PrimitiveArray result = dozer.map(test, PrimitiveArray.class);
60+
61+
// long start = System.currentTimeMillis();
62+
// result = dozer.map(test, PrimitiveArray.class);
63+
// System.out.println(System.currentTimeMillis() - start);
64+
65+
assertNotSame(test.getData(), result.getData());
66+
assertTrue(Arrays.equals(test.getData(), result.getData()));
67+
}
68+
69+
public void testReferenceCopy() {
70+
71+
FinalCopyByReferenceArray test = new FinalCopyByReferenceArray();
72+
MyDate[] data = new MyDate[1024 * 1024];
73+
for (int i = 0; i < data.length; i++) {
74+
data[i] = new MyDate(i);
75+
}
76+
test.setData(data);
77+
DozerBeanMapper dozer = new DozerBeanMapper(Arrays.asList("mappingProcessorArrayTest.xml"));
78+
FinalCopyByReferenceDest result = dozer.map(test, FinalCopyByReferenceDest.class);
79+
80+
// long start = System.currentTimeMillis();
81+
// result = dozer.map(test, FinalCopyByReferenceDest.class);
82+
// System.out.println(System.currentTimeMillis() - start);
83+
84+
assertNotSame(test.getData(), result.getData());
85+
assertTrue(Arrays.equals(test.getData(), result.getData()));
86+
}
87+
88+
}

core/src/test/java/org/dozer/MappingProcessorTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@
2323
import java.util.ArrayList;
2424
import java.util.List;
2525

26+
27+
import org.dozer.MappingProcessor;
28+
import org.junit.Before;
29+
import org.junit.Test;
30+
2631
/**
2732
* @author Dmitry Spikhalskiy
2833
* @since 03.01.13
@@ -150,4 +155,5 @@ public int hashCode() {
150155
return id;
151156
}
152157
}
158+
153159
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<mappings xmlns="http://dozer.sourceforge.net"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://dozer.sourceforge.net
5+
http://dozer.sourceforge.net/schema/beanmapping.xsd">
6+
7+
<configuration>
8+
<copy-by-references>
9+
<copy-by-reference>*MyDate</copy-by-reference>
10+
</copy-by-references>
11+
</configuration>
12+
13+
</mappings>

0 commit comments

Comments
 (0)