PropertyUtilsを利用したディープコピー。
とりあえずその場しのぎで実装してみたのが、これ。
orig が org.apache.commons.beanutils.DynaBean のケースは考慮してない。
import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.collections.Factory;
import org.apache.commons.collections.FactoryUtils;/** ディープコピー。 */
public staticT deepCopy(T orig)
throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
if (orig == null) {
return null;
}Class origClass = orig.getClass();
if (origClass.isPrimitive()
|| String.class.equals(origClass)
|| Boolean.class.equals(origClass)
|| Number.class.isAssignableFrom(origClass)) {
return orig;
} else if (origClass.isArray()) {
Object[ ] origArray = (Object[ ]) orig;
Class origComponentType = origClass.getComponentType();
int origSize = origArray.length;Object[ ] destArray = (Object[ ]) Array.newInstance(origComponentType, origSize);
for (int i = 0; i < origSize; i++) {
destArray[i] = deepCopy(origArray[i]);
}return (T) destArray;
}Factory factory = FactoryUtils.instantiateFactory(origClass);
T dest = (T) factory.create();if (dest instanceof List) {
List destList = (List) dest;
List origList = (List) orig;
int origSize = origList.size();
for (int i = 0; i < origSize; i++) {
Object origElement = origList.get(i);
Object destElement = deepCopy(origElement);
destList.add(destElement);
}
} else if (dest instanceof Map) {
Map destMap = (Map) dest;
Map origMap = (Map) orig;
Set origKeySet = origMap.keySet();
Iterator origKeyIter = origKeySet.iterator();
while (origKeyIter.hasNext()) {
Object origKey = (Object) origKeyIter.next();
Object origValue = origMap.get(origKey);
Object destValue = deepCopy(origValue);
destMap.put(origKey, destValue);
}
} else {
PropertyDescriptor origDescriptors[ ] = PropertyUtils.getPropertyDescriptors(orig);
for (int i = 0; i < origDescriptors.length; i++) {
String propName = origDescriptors[i].getName();
if (PropertyUtils.isReadable(orig, propName)) {
if (PropertyUtils.isWriteable(dest, propName)) {
Object origValue = PropertyUtils.getSimpleProperty(orig, propName);
Object destValue = deepCopy(origValue);
PropertyUtils.setSimpleProperty(dest, propName, destValue);
}
}
}
}return dest;
}
大したテストはしてないので、取り扱い注意w