package ru.simplex_software.wicket_springdata.kryo;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.springframework.data.domain.Persistable;
import java.io.Serializable;
import java.util.AbstractMap;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Модель отображения.
*
* @param <K> тип ключа, сохраняемый в БД.
* @param <V> тип значения.
*/
@Deprecated
public class KryoMapModel<K extends Persistable<? extends Serializable>, V extends Serializable> implements IModel<Map<K, V>> {
private Map<IModel<K>, IModel<V>> modelMap;
/**
* Загружена ли модель.
*/
private boolean attached;
/**
* Создание новой модели отображеия.
*
* @param map исходное отображение.
*/
public KryoMapModel(Map<K, V> map) {
this.modelMap = wrap(map);
attached = true;
}
/**
* Получение значения из модели.
*/
@Override
public Map<K, V> getObject() {
checkLoad();
return unwrap(modelMap);
}
/**
* Открепление модели.
*/
@Override
public void detach() {
modelMap.keySet().forEach(IModel::detach);
modelMap.values().forEach(IModel::detach);
attached = false;
}
/**
* Получение количества элементов.
*/
public int size() {
return modelMap.size();
}
/**
* Добавление ключа и значения.
*
* @param key ключ.
* @param value значение.
*/
public void put(K key, V value) {
put(new KryoModel<>(key), Model.of(value));
}
/**
* Добавление моделей ключа и значения.
*
* @param key модель ключа.
* @param value модель значения.
*/
public void put(IModel<K> key, IModel<V> value) {
checkLoad();
modelMap.put(key, value);
}
/**
* Получение значения по модели ключа.
*
* @param keyModel модель ключа.
* @return значение.
*/
public V get(IModel<K> keyModel) {
checkLoad();
return modelMap.get(keyModel).getObject();
}
/**
* Удаление ключа и значения по модели ключа.
*
* @param keyModel модель ключа.
*/
public void remove(IModel<K> keyModel) {
modelMap.remove(keyModel);
}
/**
* Получение итератор ключей.
*/
public Iterator<IModel<K>> getKeysIterator() {
checkLoad();
return modelMap.keySet().iterator();
}
/**
* Получение итератора ключей после сортировки.
*
* @param comparator компаратор для сортировки.
* @return итератор ключей.
*/
public Iterator<IModel<K>> getSortedModelKeysIterator(Comparator<Map.Entry<K, V>> comparator) {
checkLoad();
Comparator<Map.Entry<IModel<K>, IModel<V>>> mapComparator = (me1, me2) -> {
AbstractMap.SimpleEntry<K, V> e1 = new AbstractMap.SimpleEntry<>(me1.getKey().getObject(), me1.getValue().getObject());
AbstractMap.SimpleEntry<K, V> e2 = new AbstractMap.SimpleEntry<>(me2.getKey().getObject(), me2.getValue().getObject());
return comparator.compare(e1, e2);
};
return modelMap.entrySet().stream()
.sorted(mapComparator)
.map(Map.Entry::getKey)
.iterator();
}
/**
* Проверка загрузки и загрузка при необходимости.
*/
private void checkLoad() {
if (!attached) {
modelMap.keySet().forEach(model -> ((KryoModel<K>) model).load());
}
attached = true;
}
/**
* Оборачивание ключей и значений отображения в модели.
*
* @param map отображение.
* @return отображение моделей.
*/
private Map<IModel<K>, IModel<V>> wrap(Map<K, V> map) {
Map<IModel<K>, IModel<V>> modelMap = new LinkedHashMap<>();
map.forEach((key, value) -> modelMap.put(new KryoModel<>(key), Model.of(value)));
return modelMap;
}
/**
* Получение отображения с ключами и значениями из моделей.
*
* @param modelMap отображение моделей.
* @return отображение ключей и значений.
*/
private Map<K, V> unwrap(Map<IModel<K>, IModel<V>> modelMap) {
return modelMap.entrySet().stream()
.collect(Collectors.toMap(
entry -> entry.getKey().getObject(),
entry -> entry.getValue().getObject()));
}
}