in google-http-client/src/main/java/com/google/api/client/util/Data.java [255:320]
public static void deepCopy(Object src, Object dest) {
Class<?> srcClass = src.getClass();
Preconditions.checkArgument(srcClass == dest.getClass());
if (srcClass.isArray()) {
// clone array
Preconditions.checkArgument(Array.getLength(src) == Array.getLength(dest));
int index = 0;
for (Object value : Types.iterableOf(src)) {
Array.set(dest, index++, clone(value));
}
} else if (Collection.class.isAssignableFrom(srcClass)) {
// clone collection
@SuppressWarnings("unchecked")
Collection<Object> srcCollection = (Collection<Object>) src;
if (ArrayList.class.isAssignableFrom(srcClass)) {
@SuppressWarnings("unchecked")
ArrayList<Object> destArrayList = (ArrayList<Object>) dest;
destArrayList.ensureCapacity(srcCollection.size());
}
@SuppressWarnings("unchecked")
Collection<Object> destCollection = (Collection<Object>) dest;
for (Object srcValue : srcCollection) {
destCollection.add(clone(srcValue));
}
} else {
// clone generic data or a non-map Object
boolean isGenericData = GenericData.class.isAssignableFrom(srcClass);
if (isGenericData || !Map.class.isAssignableFrom(srcClass)) {
ClassInfo classInfo =
isGenericData ? ((GenericData) src).classInfo : ClassInfo.of(srcClass);
for (String fieldName : classInfo.names) {
FieldInfo fieldInfo = classInfo.getFieldInfo(fieldName);
// skip final fields
if (!fieldInfo.isFinal()) {
// generic data already has primitive types copied by clone()
if (!isGenericData || !fieldInfo.isPrimitive()) {
Object srcValue = fieldInfo.getValue(src);
if (srcValue != null) {
fieldInfo.setValue(dest, clone(srcValue));
}
}
}
}
} else if (ArrayMap.class.isAssignableFrom(srcClass)) {
// clone array map
@SuppressWarnings("unchecked")
ArrayMap<Object, Object> destMap = (ArrayMap<Object, Object>) dest;
@SuppressWarnings("unchecked")
ArrayMap<Object, Object> srcMap = (ArrayMap<Object, Object>) src;
int size = srcMap.size();
for (int i = 0; i < size; i++) {
Object srcValue = srcMap.getValue(i);
destMap.set(i, clone(srcValue));
}
} else {
// clone map
@SuppressWarnings("unchecked")
Map<String, Object> destMap = (Map<String, Object>) dest;
@SuppressWarnings("unchecked")
Map<String, Object> srcMap = (Map<String, Object>) src;
for (Map.Entry<String, Object> srcEntry : srcMap.entrySet()) {
destMap.put(srcEntry.getKey(), clone(srcEntry.getValue()));
}
}
}
}