Skip to content

Commit 8d2d6a8

Browse files
committed
Support Arrays.asList in GenericData cloning
Resolves #293
1 parent 346a896 commit 8d2d6a8

File tree

2 files changed

+25
-0
lines changed
  • google-http-client/src

2 files changed

+25
-0
lines changed

google-http-client/src/main/java/com/google/api/client/util/Data.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.math.BigDecimal;
2424
import java.math.BigInteger;
2525
import java.util.ArrayList;
26+
import java.util.Arrays;
2627
import java.util.Collection;
2728
import java.util.Collections;
2829
import java.util.HashSet;
@@ -216,6 +217,14 @@ public static <T> T clone(T data) {
216217
copy = (T) Array.newInstance(dataClass.getComponentType(), Array.getLength(data));
217218
} else if (data instanceof ArrayMap<?, ?>) {
218219
copy = (T) ((ArrayMap<?, ?>) data).clone();
220+
} else if ("java.util.Arrays$ArrayList".equals(dataClass.getName())) {
221+
// Arrays$ArrayList does not have a zero-arg constructor, so it has to handled specially.
222+
// Although it appears as an Object[], arrayCopy shares the same type as the array originally
223+
// passed to Arrays.asList() because Arrays$ArrayList uses clone() to create it.
224+
Object[] arrayCopy = ((List<?>) data).toArray();
225+
deepCopy(arrayCopy, arrayCopy);
226+
copy = (T) Arrays.asList(arrayCopy);
227+
return copy;
219228
} else {
220229
copy = (T) Types.newInstance(dataClass);
221230
}

google-http-client/src/test/java/com/google/api/client/util/DataTest.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,22 @@ public void testClone_arrayMap() {
116116
assertEquals(map, Data.clone(map));
117117
}
118118

119+
public void testClone_ArraysAsList() {
120+
List<Object> orig = Arrays.<Object>asList("a", "b", "c", new ArrayList<Object>());
121+
List<Object> result = Data.clone(orig);
122+
assertTrue(orig != result);
123+
assertEquals(orig, result);
124+
assertTrue(orig.get(3) != result.get(3));
125+
126+
List list = Data.clone(Arrays.asList(new String[] {"a", "b", "c"}));
127+
try {
128+
list.set(0, new Object());
129+
fail("Cloned list should be backed by String[], not Object[]");
130+
} catch (ArrayStoreException e) {
131+
// expected
132+
}
133+
}
134+
119135
public void testNewCollectionInstance() throws Exception {
120136
assertEquals(ArrayList.class, Data.newCollectionInstance(null).getClass());
121137
assertEquals(ArrayList.class, Data.newCollectionInstance(String[].class).getClass());

0 commit comments

Comments
 (0)