Newer
Older
wicketspringdata / src / main / java / ru / simplex_software / wicket_springdata / kryo / KryoModel.java
package ru.simplex_software.wicket_springdata.kryo;

import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import org.apache.wicket.injection.Injector;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.springframework.data.domain.Persistable;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Serializable;
import java.util.Iterator;
import java.util.stream.StreamSupport;

/**
 * Модель с kryo сериализацияей.
 */
public class KryoModel<P extends Persistable<? extends Serializable>> extends LoadableDetachableModel<P> {

    @SpringBean
    private AbstractKryoHolder kryoHolder;

    private byte[] data = new byte[0];
    private Class<P> clazz;

    public KryoModel() {
        inject();
    }

    public KryoModel(P entity) {
        super(entity);
        inject();
        clazz = (Class<P>) entity.getClass();
    }

    /**
     * Открепление модели.
     */
    @Override
    public void onDetach() {
        if (clazz != null) {
            Output output = new Output(new ByteArrayOutputStream());
            kryoHolder.writeObject(output, getObject());
            data = output.toBytes();
        }
    }

    @Override
    public void setObject(P entity) {
        super.setObject(entity);
        clazz = entity == null ? null : (Class<P>) entity.getClass();
    }

    /**
     * Оборачивание элементов колекции в модели и получение итератора.
     *
     * @param iterable коллекция элементов.
     * @return итератор коллекции моделей элементов.
     */
    public static <P extends Persistable<? extends Serializable>> Iterator<IModel<P>> wrapAndGetIterator(Iterable<P> iterable) {
        return StreamSupport.stream(iterable.spliterator(), false)
                .map(KryoModel::new)
                .map(km -> (IModel<P>) km)
                .iterator();
    }

    /**
     * Загрузка модели.
     *
     * @return объект модели.
     */
    @Override
    protected P load() {
        if (clazz == null) {
            return null;
        }
        Input input = new Input(new ByteArrayInputStream(data));
        return kryoHolder.readObject(input, clazz);
    }

    /**
     * Добавление в контекст Spring.
     */
    private void inject() {
        Injector.get().inject(this);
    }
}