/*
* Copyright (c) 2013-2014, Parallel Universe Software Co. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation
*
* or (per the licensee's choosing)
*
* under the terms of the GNU Lesser General Public License version 3.0
* as published by the Free Software Foundation.
*/
package co.paralleluniverse.io.serialization.kryo;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.esotericsoftware.kryo.serializers.FieldSerializer;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/**
*
* @author pron
*/
class ReplacableObjectSerializer extends FieldSerializer<Object> {
public ReplacableObjectSerializer(Kryo kryo, Class type) {
super(kryo, type);
}
@Override
public void write(Kryo kryo, Output output, Object object) {
super.write(kryo, output, getReplacement(object, "writeReplace"));
}
@Override
public Object read(Kryo kryo, Input input, Class<Object> type) {
return getReplacement(super.read(kryo, input, type), "readResolve");
}
private static Object getReplacement(Object obj, final String replaceMethodName) {
try {
Class clazz = obj.getClass();
if (!Serializable.class.isAssignableFrom(clazz))
return obj;
Method m = null;
try {
m = clazz.getDeclaredMethod(replaceMethodName);
} catch (NoSuchMethodException ex) {
Class ancestor = clazz.getSuperclass();
while (ancestor != null) {
if (!Serializable.class.isAssignableFrom(ancestor))
return obj;
try {
m = ancestor.getDeclaredMethod(replaceMethodName);
if (!Modifier.isPublic(m.getModifiers()) && !Modifier.isProtected(m.getModifiers()))
return obj;
break;
} catch (NoSuchMethodException ex1) {
ancestor = ancestor.getSuperclass();
}
}
}
if (m == null)
return obj;
m.setAccessible(true);
Object replacement = m.invoke(obj);
return replacement;
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
if (ex instanceof InvocationTargetException)
((InvocationTargetException) ex).getTargetException().printStackTrace();
return obj;
}
}
}