All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.flowlogix.jeedao.primefaces.JPALazyDataModel Maven / Gradle / Ivy

There is a newer version: 9.0.6
Show newest version
/*
 * 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;

import com.flowlogix.jeedao.primefaces.interfaces.EntityManagerGetter;
import com.flowlogix.jeedao.primefaces.interfaces.Filter;
import com.flowlogix.jeedao.primefaces.interfaces.FilterReplacer;
import com.flowlogix.jeedao.primefaces.interfaces.Initializer;
import com.flowlogix.jeedao.primefaces.interfaces.KeyConverter;
import com.flowlogix.jeedao.primefaces.interfaces.Optimizer;
import com.flowlogix.jeedao.primefaces.interfaces.Sorter;
import com.flowlogix.jeedao.primefaces.internal.JPAFacadeLocal;
import com.flowlogix.jeedao.primefaces.support.FilterData;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import java.util.List;
import java.util.Map;
import javax.enterprise.context.Dependent;
import javax.inject.Inject;
import javax.transaction.Transactional;
import org.apache.commons.lang.StringUtils;
import org.omnifaces.config.BeanManager;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortMeta;
import org.primefaces.model.SortOrder;

/**
 * Easy implementation of PrimeFaces lazy data model
 * using Lambdas
 * 
 * @author lprimak
 * @param  Key Type
 * @param  Data Type
 */
@Dependent
public class JPALazyDataModel extends LazyDataModel
{
    /**
     * Set up this particular instance of the data model
     * with entity manager, class and key converter
     * 
     * @param 
     * @param 
     * @param emg
     * @param entityClass
     * @param converter
     * @return newly-created data model
     */
    public static JPALazyDataModel createModel(EntityManagerGetter emg,
            Class entityClass, KeyConverter converter)
    {
        return createModel(emg, entityClass, converter, null);
    }
    
    
    /**
     * Set up this particular instance of the data model
     * with entity manager, class and key converter
     * 
     * @param  Key Type
     * @param  Value Type
     * @param emg
     * @param entityClass
     * @param converter 
     * @param initializer 
     * @return newly-created data model
     */
    public static JPALazyDataModel createModel(EntityManagerGetter emg,
            Class entityClass, KeyConverter converter, Initializer initializer)
    {
        @SuppressWarnings("unchecked")
        JPALazyDataModel model = BeanManager.INSTANCE.getReference(JPALazyDataModel.class);
        model.emg = emg;
        model.entityClass = entityClass;
        model.converter = converter;
        if(initializer != null)
        {
            initializer.init(model);
        }
        return model;
    }


    /**
     * set filter hook
     * 
     * @param filter 
     */
    public void setFilter(Filter filter)
    {
        this.filter = Optional.of(filter);
    }
    
    
    /**
     * remove filter hook
     */
    public void removeFilter()
    {
        filter = Optional.absent();
    }
    
     
    /**
     * Utility method for replacing a predicate in the filter list
     * 
     * @param filters filter list
     * @param element element to be replace
     * @param fp lambda to get the new Filter predicate
     */
    public void replaceFilter(Map filters, String element, FilterReplacer fp)
    {
        FilterData elt = filters.get(element);
        if (elt != null && StringUtils.isNotBlank(elt.getFieldValue()))
        {
            filters.replace(element, new FilterData(elt.getFieldValue(), 
                    fp.get(elt.getPredicate(), elt.getFieldValue())));
        }
    }

    
    /**
     * set sorter hook
     * 
     * @param sorter 
     */
    public void setSorter(Sorter sorter)
    {
        this.sorter = Optional.of(sorter);
    }
    
    
    /**
     * remove sorter hook
     */
    public void removeSorter()
    {
        sorter = Optional.absent();
    }
    

    /**
     * add hints to JPA query
     * 
     * @param optimizier 
     */
    public void addOptimizerHints(Optimizer optimizier)
    {
        this.optimizer = Optional.of(optimizier);
    }

    
    /**
     * remove hints from JPA query
     */
    public void removeOptimizerHints()
    {
        this.optimizer = Optional.absent();
    }
    
    
    /**
     * transforms JPA entity field to format suitable for hints
     * 
     * @param val
     * @return JPA field suitable for hints
     */
    public String getResultField(String val)
    {
        return String.format("%s.%s", RESULT, val);
    }
    
    
    @Override
    @SuppressWarnings("unchecked")
    @Transactional
    public KK getRowKey(TT entity)
    {
        return (KK)emg.get().getEntityManagerFactory().getPersistenceUnitUtil().getIdentifier(entity);
    }

    
    @Override
    @Transactional
    public TT getRowData(String rowKey)
    {   
        facade.setup(emg, entityClass, optimizer, filter, sorter);
        return facade.find(converter.convert(rowKey));
    }

    
    @Override
    @Transactional
    public List load(int first, int pageSize, String sortField, SortOrder sortOrder, Map filters)
    {
        SortMeta sm = new SortMeta();
        sm.setSortField(sortField);
        sm.setSortOrder(sortOrder);
        return load(first, pageSize, sortField == null? ImmutableList.of() : ImmutableList.of(sm), filters);
    }    

    
    @Override
    @Transactional
    public List load(int first, int pageSize, List multiSortMeta, Map filters)
    {
        facade.setup(emg, entityClass, optimizer, filter, sorter);
        setRowCount(facade.count(filters));
        return facade.findRows(first, pageSize, filters, multiSortMeta == null? ImmutableList.of() : multiSortMeta);
    }

    
    private @Inject JPAFacadeLocal facade;
    private EntityManagerGetter emg;
    private Class entityClass;
    private KeyConverter converter;
    private Optional> filter = Optional.absent();
    private Optional> sorter = Optional.absent();
    private Optional> optimizer = Optional.absent();
    public static final String RESULT = "result";

    private static final long serialVersionUID = 1L;
}