AbstractStore.java
/*
* Copyright © 2023-2025 The CTAN Team and individual authors
*
* This file is distributed under the 3-clause BSD license.
* See file LICENSE for details.
*/
package org.ctan.site.stores.base;
import java.util.List;
import java.util.Map;
import org.hibernate.SessionFactory;
import io.dropwizard.hibernate.AbstractDAO;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Root;
import lombok.NonNull;
/**
* The class <code>AbstractStore</code> contains the abstract repository for
* CRUD operations on an entity.
*
* @param <T> the type of the entity
* @author <a href="mailto:gene@ctan.org">Gerd Neugebauer</a>
*/
public abstract class AbstractStore<T> extends AbstractDAO<T> {
/**
* This is the constructor for <code>AbstractStore</code>.
*
* @param sessionFactory the session factory
*/
public AbstractStore(SessionFactory sessionFactory) {
super(sessionFactory);
}
/**
* The method <code>getById</code> provides means to retrieve the entity by
* its id.
*
* @param id the id
* @return the entity or {@code null} if none is present
*/
public T get(@NonNull Long id) {
return super.get(id);
}
/**
* The method <code>list</code> provides means to extract a page of items.
*
* @param term the search term
* @param page the current page
* @param pageSize the page size
* @param orderBy the order
* @param asc the indicator for ascending
* @return the page
*/
public GeneralPage list(String term, int page, int pageSize,
String orderBy, boolean asc) {
if (page < 0 || pageSize < 1) {
return null;
}
CriteriaBuilder cb = currentSession().getCriteriaBuilder();
var query = criteriaQuery();
var root = listQuery(term, cb, query);
if (orderBy != null && !orderBy.isBlank()) {
if (asc) {
query.orderBy(cb.asc(root.get(orderBy)));
} else {
query.orderBy(cb.desc(root.get(orderBy)));
}
}
var hits = list(query);
var hitCount = hits.size();
var list = hits
.subList(Math.min(page * pageSize, hitCount),
Math.min((page + 1) * pageSize, hitCount));
return new GeneralPage(hitCount, map(list));
}
/**
* The method <code>listQuery</code> provides means to construct a query for
* the list of entities for a search.
*
* @param term the search term
* @param cb the criteria builder
* @param query the query
* @return the root
*/
protected abstract Root<T> listQuery(String term, CriteriaBuilder cb,
CriteriaQuery<T> query);
/**
* The method <code>map</code> provides means to format a list for external
* use.
*
* @param list the list of entries
* @return the formatted list
*/
protected abstract List<Map<String, Object>> map(List<T> list);
/**
* The method <code>remove</code> provides means to remove a list of
* entities.
*
* @param list the list of entries
*/
public void remove(@NonNull List<T> list) {
for (var it : list) {
remove(it);
}
}
/**
* The method <code>remove</code> provides means to remove an entity by its
* id.
*
* @param id the id
* @return {@code true} iff something has been removed
*/
public boolean remove(@NonNull Long id) {
return remove(get(id));
}
/**
* The method <code>remove</code> provides means to remove an entity.
*
* @param entity the entity
* @return {@code true} iff something has been removed
*/
public boolean remove(T entity) {
if (entity == null) {
return false;
}
currentSession().remove(entity);
return true;
}
/**
* The method <code>save</code> provides means to store an entity in the
* database.
*
* @param entity the entity
* @return the entity
*/
public T save(@NonNull T entity) {
currentSession().persist(entity);
return entity;
}
}