All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.archive.bdb.AutoKryo Maven / Gradle / Ivy

package org.archive.bdb;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.SerializationException;

import sun.reflect.ReflectionFactory;

/**
 * Extensions to Kryo to let classes control their own registration, suggest
 * other classes to register together, and use the same (Sun-JVM-only) trick
 * for deserializing classes without no-arg constructors.
 * 
 * newInstance technique and constructor caching inspired by the 
 * KryoReflectionFactorySupport class of Martin Grotzke's kryo-serializers 
 * project. https://github.com/magro/kryo-serializers
 * 
 * TODO: more comments!
 * 
 * @author gojomo
 */
@SuppressWarnings("unchecked")
public class AutoKryo extends Kryo {
    protected ArrayList> registeredClasses = new ArrayList>(); 
    
    @Override
    protected void handleUnregisteredClass(@SuppressWarnings("rawtypes") Class type) {
        System.err.println("UNREGISTERED FOR KRYO "+type+" in "+registeredClasses.get(0));
        super.handleUnregisteredClass(type);
    }

    public void autoregister(Class type) {
        if (registeredClasses.contains(type)) {
            return;
        }
        registeredClasses.add(type); 
        try {
            invokeStatic(
                "autoregisterTo", 
                type,
                new Class[]{ ((Class)AutoKryo.class), }, 
                new Object[] { this, });
        } catch (Exception e) {
            register(type); 
        }
    }

    protected static final ReflectionFactory REFLECTION_FACTORY = ReflectionFactory.getReflectionFactory();
    protected static final Object[] INITARGS = new Object[0];
    protected static final Map, Constructor> CONSTRUCTOR_CACHE = new ConcurrentHashMap, Constructor>();
    
    @Override
    public  T newInstance(Class type) {
        SerializationException ex = null; 
        try {
            return super.newInstance(type);
        } catch (SerializationException se) {
            ex = se;
        }
        try {
            Constructor constructor = CONSTRUCTOR_CACHE.get(type);
            if(constructor == null) {
                constructor = REFLECTION_FACTORY.newConstructorForSerialization( 
                        type, Object.class.getDeclaredConstructor( new Class[0] ) );
                constructor.setAccessible( true );
                CONSTRUCTOR_CACHE.put(type, constructor);
            }
            Object inst = constructor.newInstance( INITARGS );
            return (T) inst;
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
             e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        throw ex;
    }

    protected Object invokeStatic(String method, Class clazz, Class[] types, Object[] args) throws Exception {
        return clazz.getMethod(method, types).invoke(null, args);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy