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<P extends Persistable<ID>, ID extends Serializable> extends Serializer<P> {
private final Function<ID, Optional<P>> findByIdFunction;
private final Class<ID> idClass;
/**
* Созания сериализатора для хранимых сущностей.
*
* @param findByIdFunction функция поиска сущности по первичному ключу.
* @param idClass класс первичного ключа сущности.
*/
public PersistableSerializer(Function<ID, Optional<P>> findByIdFunction, Class<ID> idClass) {
this.findByIdFunction = findByIdFunction;
this.idClass = idClass;
}
@Override
public void write(Kryo kryo, Output output, P entity) {
output.writeBoolean(entity.isNew());
if (entity.isNew()) {
Serializer<P> defaultSerializer = kryo.getDefaultSerializer(entity.getClass());
defaultSerializer.write(kryo, output, entity);
} else {
Serializer<Serializable> idSerializer = kryo.getSerializer(idClass);
idSerializer.write(kryo, output, entity.getId());
}
}
@Override
public P read(Kryo kryo, Input input, Class<? extends P> type) {
if (input.readBoolean()) {
Serializer<P> defaultSerializer = kryo.getDefaultSerializer(type);
return defaultSerializer.read(kryo, input, type);
} else {
Serializer<ID> idSerializer = kryo.getSerializer(idClass);
ID id = idSerializer.read(kryo, input, idClass);
return findByIdFunction.apply(id)
.orElseThrow(() -> new IllegalArgumentException("Cannot load entity of type " + type + " with id " + id));
}
}
}