package ru.simplex_software.wicket_springdata;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.springframework.data.domain.Persistable;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Модель хранимой коллекции.
*/
public class PersistableCollectionModel<P extends Persistable<? extends Serializable>> extends LoadableDetachableModel<Collection<IModel<P>>> {
/**
* Коллекция моделей.
*/
private Collection<IModel<P>> models;
public PersistableCollectionModel(Collection<IModel<P>> collection) {
this.models = collection;
}
@Override
protected Collection<IModel<P>> load() {
models.forEach(model -> ((HibernateModel<P>) model).load());
return models;
}
public boolean isEmpty() {
return models.isEmpty();
}
public void detach() {
models.forEach(IModel::detach);
}
/**
* Добавление модели.
*/
public void add(IModel<P> model) {
models.add(model);
}
/**
* Оборачивание элемента в модель и добавление в коллецию.
*/
public void add(P object) {
models.add(new HibernateModel<>(object));
}
/**
* Оборачивание элементов коллекции в модели и добавление в коллецию.
*
* @param items коллекция элементов.
*/
public void addAll(Collection<P> items) {
items.forEach(this::add);
}
/**
* Оборачивание элементов коллекции в модели и добавление в текущую коллекцию.
*
* @param objects исходная коллекция.
*/
public void wrapAndSet(Collection<P> objects) {
models.clear();
objects.stream()
.map(HibernateModel::new)
.map(hm -> (IModel<P>) hm)
.forEach(models::add);
}
/**
* Удаление модели из коллекции.
*/
public void remove(IModel<P> model) {
models.remove(model);
}
/**
* Очистка коллекции моделей.
*/
public void clear() {
models.clear();
}
/**
* Фильтрация списка модклей.
*/
public Collection<IModel<P>> filter(Predicate<P> predicate, Supplier<Collection<IModel<P>>> supplier) {
return models.stream()
.filter(model -> predicate.test(model.getObject()))
.collect(Collectors.toCollection(supplier));
}
/**
* Получение потока элементов.
*/
public Stream<P> getElementsStream() {
return models.stream()
.map(IModel::getObject);
}
/**
* Проверка наличия модели в коллекции.
*/
public boolean containsModel(IModel<P> model) {
return models.contains(model);
}
/**
* Проверка наличия объекта в коллекции.
*/
public boolean containsModelObject(P object) {
return !unwrapAndFilter(item -> item.equals(object), HashSet::new).isEmpty();
}
/**
* Получение итератора коллеции моделей.
*/
public Iterator<IModel<P>> getModelsIterator() {
return models.iterator();
}
/**
* Получение развернутых элементов коллекции.
*
* @param supplier поставщик коллекции элементов.
* @return коллекция развернутых элементов.
*/
public <C extends Collection<P>> C unwrapAndGet(Supplier<C> supplier) {
return models.stream()
.map(IModel::getObject)
.collect(Collectors.toCollection(supplier));
}
/**
* Получение развернутых элементов с учетом фильтра.
*
* @param predicate условие фильтрации.
* @param supplier поставщик коллекции элементов.
* @return коллекция развернутых элементов.
*/
public <C extends Collection<P>> C unwrapAndFilter(Predicate<P> predicate, Supplier<C> supplier) {
return models.stream()
.map(IModel::getObject)
.filter(predicate)
.collect(Collectors.toCollection(supplier));
}
}