diff --git a/pom.xml b/pom.xml index 5b82632..b739b42 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ ru.simplex_software wicket-springdata - 1.2 + 1.3 wicket-springdata http://www.simplex-software.ru @@ -28,6 +28,14 @@ + + + + com.esotericsoftware + kryo + 5.0.0-RC4 + + junit junit diff --git a/src/main/java/ru/simplex_software/wicket_springdata/kryo/AbstractKryoHolder.java b/src/main/java/ru/simplex_software/wicket_springdata/kryo/AbstractKryoHolder.java new file mode 100644 index 0000000..4bf94f2 --- /dev/null +++ b/src/main/java/ru/simplex_software/wicket_springdata/kryo/AbstractKryoHolder.java @@ -0,0 +1,30 @@ +package ru.simplex_software.wicket_springdata.kryo; + +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.io.Input; +import com.esotericsoftware.kryo.io.Output; +import org.springframework.data.domain.Persistable; + +import java.io.Serializable; + +/** + * Загрузка и настройка Kryo. + */ +public abstract class AbstractKryoHolder { + + protected Kryo kryo = new Kryo(); + + /** + * Сериализация объекта. + */ + public

> void writeObject(Output output, P entity) { + kryo.writeObject(output, entity); + } + + /** + * Десериализация объекта. + */ + public

> P readObject(Input input, Class

type) { + return kryo.readObject(input, type); + } +} \ No newline at end of file diff --git a/src/main/java/ru/simplex_software/wicket_springdata/kryo/KryoModel.java b/src/main/java/ru/simplex_software/wicket_springdata/kryo/KryoModel.java new file mode 100644 index 0000000..c1b2136 --- /dev/null +++ b/src/main/java/ru/simplex_software/wicket_springdata/kryo/KryoModel.java @@ -0,0 +1,72 @@ +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

> extends LoadableDetachableModel

{ + + @SpringBean + private AbstractKryoHolder kryoHolder; + + private byte[] data = new byte[0]; + private Class

clazz; + + public KryoModel(P entity) { + super(entity); + inject(); + clazz = (Class

) entity.getClass(); + } + + @Override + public void onDetach() { + Output output = new Output(new ByteArrayOutputStream()); + kryoHolder.writeObject(output, getObject()); + data = output.toBytes(); + } + + @Override + public void setObject(P entity) { + super.setObject(entity); + clazz = (Class

) entity.getClass(); + } + + /** + * Оборачивание элементов колекции в модели и получение итератора. + * + * @param iterable коллекция элементов. + * @return итератор коллекции моделей элементов. + */ + public static

> Iterator> wrapAndGetIterator(Iterable

iterable) { + return StreamSupport.stream(iterable.spliterator(), false) + .map(KryoModel::new) + .map(km -> (IModel

) km) + .iterator(); + } + + @Override + protected P load() { + Input input = new Input(new ByteArrayInputStream(data)); + return kryoHolder.readObject(input, clazz); + } + + /** + * Добавление в контекст Spring. + */ + private void inject() { + Injector.get().inject(this); + } +} diff --git a/src/main/java/ru/simplex_software/wicket_springdata/kryo/PersistableSerializer.java b/src/main/java/ru/simplex_software/wicket_springdata/kryo/PersistableSerializer.java new file mode 100644 index 0000000..d827708 --- /dev/null +++ b/src/main/java/ru/simplex_software/wicket_springdata/kryo/PersistableSerializer.java @@ -0,0 +1,49 @@ +package ru.simplex_software.wicket_springdata.kryo; + +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.Serializer; +import com.esotericsoftware.kryo.io.Input; +import com.esotericsoftware.kryo.io.Output; +import org.springframework.data.domain.Persistable; + +import java.io.Serializable; +import java.util.Optional; +import java.util.function.Function; + +/** + * Чтение и запись хранимых сущностей. + */ +public class PersistableSerializer

, ID extends Serializable> extends Serializer

{ + + private Function> findByIsFunction; + private Class idClass; + + public PersistableSerializer(Function> findByIsFunction, Class idClass) { + this.findByIsFunction = findByIsFunction; + this.idClass = idClass; + } + + @Override + public void write(Kryo kryo, Output output, P entity) { + output.writeBoolean(entity.isNew()); + if (entity.isNew()) { + Serializer

defaultSerializer = kryo.getDefaultSerializer(entity.getClass()); + defaultSerializer.write(kryo, output, entity); + } else { + Serializer idSerializer = kryo.getSerializer(idClass); + idSerializer.write(kryo, output, entity.getId()); + } + } + + @Override + public P read(Kryo kryo, Input input, Class type) { + if (input.readBoolean()) { + Serializer

defaultSerializer = kryo.getDefaultSerializer(type); + return defaultSerializer.read(kryo, input, type); + } else { + Serializer idSerializer = kryo.getSerializer(idClass); + ID id = idSerializer.read(kryo, input, idClass); + return findByIsFunction.apply(id).get(); + } + } +}