package org.brixcms.plugin.jpa.web.admin; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import org.apache.wicket.injection.Injector; import org.apache.wicket.model.IModel; import org.apache.wicket.spring.injection.annot.SpringBean; import org.brixcms.plugin.jpa.JpaPluginLocator; import org.brixcms.plugin.jpa.Persistable; import org.brixcms.plugin.jpa.web.admin.filter.FilterPanel.FilterPluginEntry; import com.inmethod.grid.IDataSource; import com.inmethod.grid.IGridSortState; import com.inmethod.grid.IGridSortState.ISortStateColumn; /** * @author dan.simko@gmail.com */ @SuppressWarnings("serial") public class GridDataSource<T extends Persistable<ID>, ID extends Serializable, F extends Serializable> implements IDataSource<T> { @SpringBean private EntityManager entityManager; private final JpaPluginLocator<T, ID, F> pluginLocator; private final List<FilterPluginEntry<T, ID, F>> filters = new ArrayList<>(); public GridDataSource(JpaPluginLocator<T, ID, F> pluginLocator) { Injector.get().inject(this); this.pluginLocator = pluginLocator; } @Override public IModel<T> model(T object) { return new EntityModel<T, ID>(object); } @Override public void query(IQuery query, IQueryResult<T> result) { CriteriaBuilder builder = entityManager.getCriteriaBuilder(); CriteriaQuery<T> criteriaQuery = builder.createQuery(pluginLocator.getPlugin().getEntityClass()); CriteriaQuery<Long> countCriteriaQuery = builder.createQuery(Long.class); Root<T> root = criteriaQuery.from(pluginLocator.getPlugin().getEntityClass()); Root<T> countRoot = countCriteriaQuery.from(pluginLocator.getPlugin().getEntityClass()); applyFilter(builder, criteriaQuery, root); applyFilter(builder, countCriteriaQuery, countRoot); // is there any sorting if (query.getSortState().getColumns().size() > 0) { // get the most relevant column ISortStateColumn<Object> state = (ISortStateColumn<Object>) query.getSortState().getColumns().get(0); // get the column sort properties String sortProperty = state.getPropertyName().toString(); boolean sortAsc = state.getDirection() == IGridSortState.Direction.ASC; criteriaQuery.orderBy(sortAsc ? builder.asc(root.get(sortProperty)) : builder.desc(root.get(sortProperty))); } result.setTotalCount(entityManager.createQuery(countCriteriaQuery.select(builder.count(countRoot))).getSingleResult()); result.setItems(entityManager.createQuery(criteriaQuery.select(root)).setFirstResult((int) query.getFrom()) .setMaxResults((int) query.getCount()).getResultList().iterator()); } private void applyFilter(CriteriaBuilder builder, CriteriaQuery<?> criteriaQuery, Root<T> root) { for (FilterPluginEntry<T, ID, F> filterEntry : filters) { List<Predicate> predicates = filterEntry.getPlugin().createPredicate(builder, root, filterEntry.getFilter()); if (!predicates.isEmpty()) { criteriaQuery.where(builder.and(predicates.toArray(new Predicate[0]))); } } } public List<FilterPluginEntry<T, ID, F>> getFilters() { return filters; } @Override public void detach() { } }