com.flowlogix.jeedao.primefaces.internal.JPAFacade Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of flowlogix-datamodel Show documentation
Show all versions of flowlogix-datamodel Show documentation
Flow Logix PrimeFaces Lazy Data Model
/*
* Copyright 2014 lprimak.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.flowlogix.jeedao.primefaces.internal;
import com.flowlogix.jeedao.impl.AbstractFacade;
import com.flowlogix.jeedao.primefaces.JPALazyDataModel;
import com.flowlogix.jeedao.primefaces.interfaces.EntityManagerGetter;
import com.flowlogix.jeedao.primefaces.interfaces.Filter;
import com.flowlogix.jeedao.primefaces.interfaces.Optimizer;
import com.flowlogix.jeedao.primefaces.interfaces.Sorter;
import com.flowlogix.jeedao.primefaces.support.FilterData;
import com.flowlogix.jeedao.primefaces.support.SortData;
import com.flowlogix.util.TypeConverter;
import com.google.common.base.Optional;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.util.List;
import java.util.Map;
import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Order;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import lombok.extern.slf4j.Slf4j;
import org.primefaces.model.SortMeta;
/**
* JPA DAO facade implementation for the PrimeFaces lazy table model
* @author lprimak
* @param
* @param
*/
@Stateless @Slf4j
public class JPAFacade extends AbstractFacade implements JPAFacadeLocal
{
@Override
public void setup(EntityManagerGetter emg, Class entityClass, Optional> optimizer,
Optional> filter, Optional> sorter)
{
getState().setEmg(emg);
getState().setEntityClass(entityClass);
getState().setOptimizer(optimizer);
getState().setFilterHook(filter);
getState().setSorterHook(sorter);
}
@Override
protected EntityManager getEntityManager()
{
return getState().getEmg().get();
}
@Override
public Class getEntityClass()
{
return getState().getEntityClass();
}
@Override
public int count(Map filters)
{
getState().setFilters(filters);
getState().setSortMeta(Lists.newLinkedList());
return super.count();
}
@Override
public List findRows(int first, int pageSize, Map filters, List sortMeta)
{
getState().setFilters(filters);
getState().setSortMeta(sortMeta);
return super.findRange(new int[] { first, first + pageSize });
}
@Override
protected void addToCriteria(CriteriaBuilder cb, Root root, CriteriaQuery cq)
{
cq.where(getFilters(getState().getFilters(), cb, root));
cq.orderBy(getSort(getState().getSortMeta(), cb, root));
root.alias(JPALazyDataModel.RESULT);
}
@Override
protected void addToCountCriteria(CriteriaBuilder cb, Root root, CriteriaQuery cq)
{
cq.where(getFilters(getState().getFilters(), cb, root));
}
@Override
protected void addHints(TypedQuery tq, boolean isRange)
{
if(getState().getOptimizer().isPresent())
{
getState().getOptimizer().get().addHints(tq);
}
}
private Predicate getFilters(Map filters, CriteriaBuilder cb, Root root)
{
Map predicates = Maps.newHashMap();
filters.forEach((key, value) ->
{
Predicate cond = null;
try
{
Class> fieldType = root.get(key).getJavaType();
if (fieldType == String.class)
{
cond = cb.like(root.get(key), String.format("%%%s%%", value));
} else
{
if (TypeConverter.checkType(value.toString(), fieldType))
{
cond = cb.equal(root.get(key), value);
}
}
}
catch(IllegalArgumentException e) { /* ignore possibly extra filter fields */}
predicates.put(key, new FilterData(value.toString(), cond));
});
if(getState().getFilterHook().isPresent())
{
getState().getFilterHook().get().filter(predicates, cb, root);
}
return cb.and(FluentIterable.from(predicates.values())
.filter(it -> it.getPredicate() != null)
.transform(it -> it.getPredicate()).toArray(Predicate.class));
}
private List getSort(List sortCriteria, CriteriaBuilder cb, Root root)
{
SortData sortData = new SortData(sortCriteria);
if(getState().getSorterHook().isPresent())
{
getState().getSorterHook().get().sort(sortData, cb, root);
}
List sortMetaOrdering = processSortMeta(sortData.getSortMeta(), cb, root);
List rv = Lists.newLinkedList();
if(sortData.isAppendSortOrder())
{
rv.addAll(sortMetaOrdering);
rv.addAll(sortData.getSortOrder());
}
else
{
rv.addAll(sortData.getSortOrder());
rv.addAll(sortMetaOrdering);
}
return rv;
}
private List processSortMeta(List sortMeta, CriteriaBuilder cb, Root root)
{
List sortMetaOrdering = Lists.newLinkedList();
sortMeta.forEach(sm ->
{
switch(sm.getSortOrder())
{
case ASCENDING:
sortMetaOrdering.add(cb.asc(root.get(sm.getSortField())));
break;
case DESCENDING:
sortMetaOrdering.add(cb.desc(root.get(sm.getSortField())));
break;
}
});
return sortMetaOrdering;
}
@SuppressWarnings("unchecked")
private JPAFacadeTypedState getState()
{
return (JPAFacadeTypedState) state.getTypedState();
}
private @Inject JPAFacadeState state;
}