Fixed storage so that it copies fields from the entire object hierarchy
This commit is contained in:
parent
d1fb857cc0
commit
9dfe590a80
@ -25,8 +25,6 @@ import com.esotericsoftware.kryo.io.Output;
|
|||||||
* Nothing spectacular about this storage -- it allows for persistent storage of objects to disk.
|
* Nothing spectacular about this storage -- it allows for persistent storage of objects to disk.
|
||||||
*/
|
*/
|
||||||
public class Storage {
|
public class Storage {
|
||||||
// TODO: add snappy compression to storage objects??
|
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(Storage.class);
|
private static final Logger logger = LoggerFactory.getLogger(Storage.class);
|
||||||
|
|
||||||
private static Map<File, Storage> storages = new HashMap<File, Storage>(1);
|
private static Map<File, Storage> storages = new HashMap<File, Storage>(1);
|
||||||
@ -49,7 +47,6 @@ public class Storage {
|
|||||||
throw new IllegalArgumentException("loadIntoObject cannot be null!");
|
throw new IllegalArgumentException("loadIntoObject cannot be null!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// if we load from a NEW storage at the same location as an ALREADY EXISTING storage,
|
// if we load from a NEW storage at the same location as an ALREADY EXISTING storage,
|
||||||
// without saving the existing storage first --- whoops!
|
// without saving the existing storage first --- whoops!
|
||||||
synchronized (storages) {
|
synchronized (storages) {
|
||||||
@ -76,7 +73,7 @@ public class Storage {
|
|||||||
storage.objectReference = new WeakReference(loadIntoObject);
|
storage.objectReference = new WeakReference(loadIntoObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (source != null) {
|
if (source != null && source != orig) {
|
||||||
copyFields(source, loadIntoObject);
|
copyFields(source, loadIntoObject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -294,45 +291,57 @@ public class Storage {
|
|||||||
|
|
||||||
private static void copyFields(Object source, Object dest) {
|
private static void copyFields(Object source, Object dest) {
|
||||||
Class<? extends Object> sourceClass = source.getClass();
|
Class<? extends Object> sourceClass = source.getClass();
|
||||||
Field[] destFields = dest.getClass().getDeclaredFields();
|
Class<? extends Object> destClass = dest.getClass();
|
||||||
|
|
||||||
for (Field destField : destFields) {
|
if (sourceClass != destClass) {
|
||||||
String name = destField.getName();
|
throw new IllegalArgumentException("Source and Dest objects are not of the same class!");
|
||||||
try {
|
}
|
||||||
Field sourceField = sourceClass.getDeclaredField(name);
|
|
||||||
destField.setAccessible(true);
|
|
||||||
sourceField.setAccessible(true);
|
|
||||||
|
|
||||||
Object sourceObj = sourceField.get(source);
|
// have to walk up the object hierarchy.
|
||||||
|
while (destClass != Object.class) {
|
||||||
|
Field[] destFields = destClass.getDeclaredFields();
|
||||||
|
|
||||||
if (sourceObj instanceof Map) {
|
for (Field destField : destFields) {
|
||||||
Object destObj = destField.get(dest);
|
String name = destField.getName();
|
||||||
if (destObj == null) {
|
try {
|
||||||
destField.set(dest, sourceObj);
|
Field sourceField = sourceClass.getDeclaredField(name);
|
||||||
} else if (destObj instanceof Map) {
|
destField.setAccessible(true);
|
||||||
@SuppressWarnings("unchecked")
|
sourceField.setAccessible(true);
|
||||||
Map<Object, Object> sourceMap = (Map<Object, Object>) sourceObj;
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
Map<Object, Object> destMap = (Map<Object, Object>) destObj;
|
|
||||||
|
|
||||||
destMap.clear();
|
Object sourceObj = sourceField.get(source);
|
||||||
Iterator<?> entries = sourceMap.entrySet().iterator();
|
|
||||||
while (entries.hasNext()) {
|
if (sourceObj instanceof Map) {
|
||||||
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)entries.next();
|
Object destObj = destField.get(dest);
|
||||||
Object key = entry.getKey();
|
if (destObj == null) {
|
||||||
Object value = entry.getValue();
|
destField.set(dest, sourceObj);
|
||||||
destMap.put(key, value);
|
} else if (destObj instanceof Map) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Map<Object, Object> sourceMap = (Map<Object, Object>) sourceObj;
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Map<Object, Object> destMap = (Map<Object, Object>) destObj;
|
||||||
|
|
||||||
|
destMap.clear();
|
||||||
|
Iterator<?> entries = sourceMap.entrySet().iterator();
|
||||||
|
while (entries.hasNext()) {
|
||||||
|
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)entries.next();
|
||||||
|
Object key = entry.getKey();
|
||||||
|
Object value = entry.getValue();
|
||||||
|
destMap.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
logger.error("Incompatible field type! '{}'", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
logger.error("Incompatible field type! '{}'", name);
|
destField.set(dest, sourceObj);
|
||||||
}
|
}
|
||||||
} else {
|
} catch (Exception e) {
|
||||||
destField.set(dest, sourceObj);
|
logger.error("Unable to copy field: {}", name, e);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error("Unable to copy field: {}", name, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destClass = destClass.getSuperclass();
|
||||||
|
sourceClass = sourceClass.getSuperclass();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user