Archiviert
13
0

Add the ability to clonse java.util.Arrays$ArrayList.

Dieser Commit ist enthalten in:
Kristian S. Stangeland 2014-04-16 02:45:00 +02:00
Ursprung 486ac2653d
Commit 3bd1361c9a
3 geänderte Dateien mit 49 neuen und 17 gelöschten Zeilen

Datei anzeigen

@ -17,6 +17,7 @@
package com.comphenix.protocol.reflect.cloning; package com.comphenix.protocol.reflect.cloning;
import java.io.Serializable;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.util.Collection; import java.util.Collection;
@ -55,32 +56,37 @@ public class CollectionCloner implements Cloner {
throw new IllegalArgumentException("source cannot be NULL."); throw new IllegalArgumentException("source cannot be NULL.");
Class<?> clazz = source.getClass(); Class<?> clazz = source.getClass();
if (source instanceof Collection) { if (source instanceof Collection) {
Collection<Object> copy = cloneConstructor(Collection.class, clazz, source); Collection<Object> copy = cloneConstructor(Collection.class, clazz, source);
// Next, clone each element in the collection // Next, clone each element in the collection
copy.clear(); try {
copy.clear();
for (Object element : (Collection<Object>) source) {
copy.add(getClone(element, source)); for (Object element : (Collection<Object>) source) {
copy.add(getClone(element, source));
}
} catch (UnsupportedOperationException e) {
// Immutable - we can't do much about that
} }
return copy; return copy;
} else if (source instanceof Map) { } else if (source instanceof Map) {
Map<Object, Object> copy = cloneConstructor(Map.class, clazz, source); Map<Object, Object> copy = cloneConstructor(Map.class, clazz, source);
// Next, clone each element in the collection // Next, clone each element in the collection
copy.clear(); try {
copy.clear();
for (Entry<Object, Object> element : ((Map<Object, Object>) source).entrySet()) {
Object key = getClone(element.getKey(), source); for (Entry<Object, Object> element : ((Map<Object, Object>) source).entrySet()) {
Object value = getClone(element.getValue(), source); Object key = getClone(element.getKey(), source);
copy.put(key, value); Object value = getClone(element.getValue(), source);
copy.put(key, value);
}
} catch (UnsupportedOperationException e) {
// Immutable - we can't do much about that
} }
return copy; return copy;
} else if (clazz.isArray()) { } else if (clazz.isArray()) {
@ -163,12 +169,14 @@ public class CollectionCloner implements Cloner {
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private <T> T cloneConstructor(Class<?> superclass, Class<?> clazz, Object source) { private <T> T cloneConstructor(Class<?> superclass, Class<?> clazz, Object source) {
// Not all collections or maps implement "clone", but most *do* implement the "copy constructor" pattern // Not all collections or maps implement "clone", but most *do* implement the "copy constructor" pattern
try { try {
Constructor<?> constructCopy = clazz.getConstructor(Collection.class); Constructor<?> constructCopy = clazz.getConstructor(Collection.class);
return (T) constructCopy.newInstance(source); return (T) constructCopy.newInstance(source);
} catch (NoSuchMethodException e) { } catch (NoSuchMethodException e) {
if (source instanceof Serializable)
return (T) new SerializableCloner().clone(source);
// Delegate to serializable if possible
return (T) cloneObject(clazz, source); return (T) cloneObject(clazz, source);
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException("Cannot construct collection.", e); throw new RuntimeException("Cannot construct collection.", e);

Datei anzeigen

@ -21,7 +21,7 @@ public class SerializableCloner implements Cloner {
@Override @Override
public Object clone(Object source) { public Object clone(Object source) {
return clone(source); return SerializableCloner.clone((Serializable)source);
} }
/** /**

Datei anzeigen

@ -0,0 +1,24 @@
package com.comphenix.protocol.reflect.cloning;
import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.List;
import org.junit.BeforeClass;
import org.junit.Test;
import com.comphenix.protocol.BukkitInitialization;
public class AggregateClonerTest {
@BeforeClass
public static void initializeBukkit() throws IllegalAccessException {
BukkitInitialization.initializePackage();
}
@Test
public void testArrays() {
List<Integer> input = Arrays.asList(1, 2, 3);
assertEquals(input, AggregateCloner.DEFAULT.clone(input));
}
}