package ru.simplex_software.wicket_springdata;
import org.apache.wicket.injection.Injector;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.hibernate.Hibernate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Persistable;
import org.springframework.data.repository.CrudRepository;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* Модель содержит:
* Persistable сущность в прикреплённом состоянии,
* id и класс Persistable сущности в откреплённом состоянии.
*/
public class HibernateModel<T extends Persistable<? extends Serializable>> extends LoadableDetachableModel<T> {
private static final Logger LOG = LoggerFactory.getLogger(HibernateModel.class);
@SpringBean
private RepositoryFinder repositoryFinder;
/**
* Первичный кдюч хранимой сущности
*/
private Serializable id;
/**
* Класс хранимой сущности
*/
private Class<T> tClass;
public HibernateModel() {
init();
}
/**
* Конструктор.
*
* @param entity может быть NULL.
*/
public HibernateModel(T entity) {
super(entity);
init();
setObject(entity);
}
public void setObject(T entity) {
if (entity != null && entity.isNew()) {
throw new IllegalArgumentException("primary key can't be null");
}
super.setObject(entity);
}
/**
* Открепление сущности.
*/
public void onDetach() {
LOG.debug("onDetach start");
// Получаем Persistable сущность.
T entity = getObject();
if (entity == null) {
return;
}
// Получаем Id и класс Persistable сущности.
id = entity.getId();
tClass = (Class<T>) Hibernate.getClass(entity);
LOG.debug("onDetach end");
}
private void init() {
Injector.get().inject(this);
}
@Override
protected T load() {
LOG.debug("load start");
if (isAttached()) {
return getObject();
}
if (tClass == null) {
return null;
}
final CrudRepository repository = repositoryFinder.findRepository(tClass);
LOG.trace("repository={}", repository);
return (T) repository.findById(id).get();
}
/**
* Оборачивает в модели элементы списка.
*/
public static <E extends Persistable<? extends Serializable>> List<HibernateModel<E>> wrapElements(List<E> list) {
final ArrayList<HibernateModel<E>> models = new ArrayList<>(list.size());
for (E e : list) {
models.add(new HibernateModel<>(e));
}
return models;
}
/**
* Оборачивает в модели элементы списка и возвращает итератор.
*/
public static <E extends Persistable<? extends Serializable>> Iterator<HibernateModel<E>> wrapAndIterateElements(List<E> list) {
final ArrayList<HibernateModel<E>> models = new ArrayList<>(list.size());
for (E e : list) {
models.add(new HibernateModel<>(e));
}
return models.iterator();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (id == null) {
onDetach();
}
if (id == null) {//if no object set
if (o instanceof HibernateModel) {
Object obj = ((HibernateModel) o).getObject();
return obj == null;
}
return false;
}
if (o == null || getClass() != o.getClass()) return false;
HibernateModel<?> that = (HibernateModel<?>) o;
if (!id.equals(that.id)) return false;
return tClass.equals(that.tClass);
}
@Override
public int hashCode() {
if (id == null) {
onDetach(); // Для установки Id
}
if (id == null) { // if no object set
return -1;
} else {
return id.hashCode();
}
}
public RepositoryFinder getRepositoryFinder() {
return repositoryFinder;
}
public void setRepositoryFinder(RepositoryFinder repositoryFinder) {
this.repositoryFinder = repositoryFinder;
}
}