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

br.com.jarch.faces.controller.CrudDataDetail Maven / Gradle / Ivy

package br.com.jarch.faces.controller;

import br.com.jarch.core.annotation.*;
import br.com.jarch.core.crud.search.ISearch;
import br.com.jarch.core.crud.service.ICrudService;
import br.com.jarch.core.crud.util.CloneEntityUtils;
import br.com.jarch.core.exception.InsertException;
import br.com.jarch.core.model.*;
import br.com.jarch.core.model.type.ActionCrudType;
import br.com.jarch.core.util.BundleUtils;
import br.com.jarch.faces.util.JavaScriptUtils;
import br.com.jarch.faces.util.JsfUtils;
import br.com.jarch.util.LogUtils;
import br.com.jarch.util.ReflectionUtils;

import javax.annotation.PostConstruct;
import javax.enterprise.event.Event;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.validation.groups.Default;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public abstract class CrudDataDetail implements IDataDetail, Serializable {

    @Inject
    private ICrudService service;

    @Inject
    private ISearch search;

    @Inject
    @JArchEventDataDetailStartEnviromentInsert
    private Event> eventStartInsert;

    @Inject
    @JArchEventDataDetailStartEnviromentClone
    private Event> eventStartClone;

    @Inject
    @JArchEventDataDetailStartEnviromentChange
    private Event> eventStartChange;

    @Inject
    @JArchEventDataDetailStartEnviromentConsult
    private Event> eventStartConsult;

    @Inject
    @JArchEventDataDetailStartEnviromentDelete
    private Event> eventStartDelete;

    @Inject
    @JArchEventDataDetailStartEnviromentDynamic
    private Event> eventStartDynamic;

    @Inject
    @JArchEventValidInsert
    private Event validInsert;

    @Inject
    @JArchEventValidInsertChange
    private Event validInsertChange;

    @Inject
    @JArchEventValidChange
    private Event validChange;

    @Inject
    @JArchEventValidDelete
    private Event validDelete;

    private ColumnsList listColumnDataTable;

    private IAcessMenu acessMenu;

    private E entity;

    private E originalEntity;

    private Collection listBeforeChange;

    private ICrudEntity entityMaster;

    private ActionCrudType action;

    private boolean disableInsert;

    private boolean disableChange;

    private boolean disableConsult;

    private boolean disableDelete;

    private boolean required;

    private boolean blocked;

    private boolean modeShowData;

    private String classCollapse;

    private transient JArchDynamicDetailShowDataController annotationDynamic;

    private LazyDataModelPaginator dataModel;

    private transient Predicate filterDataModel;

    private transient Comparator orderDataModel;

    private transient Runnable processStartEnviroment;

    private transient Consumer processBeforeSave;

    private transient Consumer processAfterSave;

    private transient Consumer processBeforeDelete;

    private transient Consumer processAfterDelete;

    private transient Consumer processAfterCancel;

    private List selections = new ArrayList<>();

    @PostConstruct
    private void init() {
        startEnviroment();
    }

    public E getEntity() {
        return entity;
    }

    public void setEntity(E entity) {
        this.entity = entity;
    }

    public Predicate getFilterDataModel() {
        return filterDataModel;
    }

    public void setFilterDataModel(Predicate filterDataModel) {
        this.filterDataModel = filterDataModel;
    }

    public Comparator getOrderDataModel() {
        return orderDataModel;
    }

    public void setOrderDataModel(Comparator orderDataModel) {
        this.orderDataModel = orderDataModel;
    }

    public ICrudService getService() {
        return service;
    }

    public ISearch getSearch() {
        return search;
    }

    public ActionCrudType getAction() {
        return action;
    }

    public void setAction(ActionCrudType action) {
        this.action = action;
    }

    public String getClassCollapse() {
        return classCollapse;
    }

    public void setClassCollapse(String classCollapse) {
        this.classCollapse = classCollapse;
    }

    @Override
    public List getListColumnDataTable() {
        if (listColumnDataTable == null) {
            LogUtils.warning("JARCH ERROR: CrudDataDetail " + this.getClass().getSimpleName() + " não configurado as colunas @JArchColumnDataTable");
            return new ArrayList<>();
        }

        return listColumnDataTable.stream().filter(IColumnList::isVisible).collect(Collectors.toList());
    }

    @Override
    public void setListColumnDataTable(ColumnsList listColumnDataTable) {
        this.listColumnDataTable = listColumnDataTable;
    }

    public List getSelections() {
        return selections;
    }

    public void setSelections(List selections) {
        this.selections = selections;
    }


    public boolean isRequired() {
        return required;
    }

    public Optional getColumnDataTable(String field) {
        return listColumnDataTable.stream().filter(c -> c.getField().equals(field)).findAny();
    }

    public LazyDataModelPaginator createDataModelFromMaster(ICrudEntity entityMaster) {
        this.entityMaster = entityMaster;

        if (entityMaster != null && dataModel == null || dataModel.getRowCount() == 0/* || !entityMaster.equals(this.entityMaster)*/) {
            configureDataModel();
        }

        return dataModel;
    }

    public LazyDataModelPaginator createDataModelFromMasterDirect(ICrudEntity entityMaster) {
        this.entityMaster = entityMaster;
        configureDataModel();
        return dataModel;
    }

//    public void createDataModelFromCollection(Collection listEntity) {
//        List listReturn = new ArrayList<>();
//
//        listReturn.addAll(listEntity);
//
//        if (predicateDataModel != null) {
//            listReturn = listReturn.stream().filter(predicateDataModel).collect(Collectors.toList());
//        }
//
//        if (orderDataModel != null) {
//            listReturn = listReturn.stream().sorted(orderDataModel).collect(Collectors.toList());
//        }
//
//        dataModel = new LazyDataModelPaginator<>(listReturn, search);
//    }

    public boolean isDisableInsert() {
        return disableInsert;
    }

    public void setDisableInsert(boolean disableInsert) {
        this.disableInsert = disableInsert;
    }

    public boolean isDisableChange() {
        return disableChange;
    }

    public void setDisableChange(boolean disableChange) {
        this.disableChange = disableChange;
    }

    public boolean isDisableConsult() {
        return disableConsult;
    }

    public void setDisableConsult(boolean disableConsult) {
        this.disableConsult = disableConsult;
    }

    public boolean isDisableDelete() {
        return disableDelete;
    }

    public void setDisableDelete(boolean disableDelete) {
        this.disableDelete = disableDelete;
    }

    public void validInsert() {
        validInsert.fire(entity);
        validInsertChange.fire(entity);
        service.validInsert(entity);
    }

    public void validClone() {
        validInsert();
    }

    public void validChange() {
        validChange.fire(entity);
        validInsertChange.fire(entity);
        service.validChange(entity);
    }

    public void validDelete() {
        validDelete.fire(entity);
        service.validDelete(entity);
    }

    public void insert() {
        try {
            if (isModeShowData()) {
                if (action.isInsert())
                    showDataTab();

                JavaScriptUtils.showMessageHeaderWarning(BundleUtils.messageBundle("label.atencao"), BundleUtils.messageBundle("message.dataDetailRegisterModeEdition"));
                return;
            }

            this.annotationDynamic = null;
            action = ActionCrudType.INSERT;
            entity = service.createEntity();
            saveEntityMasterInDetail();
            eventStartInsert.fire(this);
            required = true;
            modeShowData = true;
            showDataTab();

            if (processStartEnviroment != null)
                processStartEnviroment.run();

            collapseIn();
        } catch (Exception e) {
            LogUtils.generate(e);
            JavaScriptUtils.showMessageHeaderError(e);
        }
    }

    public void clone(E entity) {
        try {
            if (isModeShowData()) {
                if (action.isClone())
                    showDataTab();

                JavaScriptUtils.showMessageHeaderWarning(BundleUtils.messageBundle("label.atencao"), BundleUtils.messageBundle("message.dataDetailRegisterModeEdition"));
                return;
            }

            this.annotationDynamic = null;
            action = ActionCrudType.CLONE;
            this.entity = service.cloneEntity(entity);
            eventStartClone.fire(this);
            required = true;
            modeShowData = true;

            if (processStartEnviroment != null)
                processStartEnviroment.run();


            collapseIn();
        } catch (Exception e) {
            LogUtils.generate(e);
            JavaScriptUtils.showMessageHeaderError(e);
        }
    }

    public void change(E entity) {
        try {
            if (isModeShowData()) {
                if (action.isChange())
                    showDataTab();

                JavaScriptUtils.showMessageHeaderWarning(BundleUtils.messageBundle("label.atencao"), BundleUtils.messageBundle("message.dataDetailRegisterModeEdition"));
                return;
            }

            originalEntity = CloneEntityUtils.clone(entity);
            originalEntity.setId(entity.getId());
            saveListBeforeChange();
            removeEntityFromEntityMaster(entity);
            this.entity = service.cloneEntity(entity, false);
            this.entity.setId(entity.getId());
            this.annotationDynamic = null;
            action = ActionCrudType.CHANGE;
            this.entity = entity;
            eventStartChange.fire(this);
            required = true;
            modeShowData = true;

            if (processStartEnviroment != null)
                processStartEnviroment.run();

            collapseIn();
        } catch (Exception e) {
            LogUtils.generate(e);
            JavaScriptUtils.showMessageHeaderError(e);
        }
    }

    public void consult(E entity) {
        try {
            if (isModeShowData()) {
                JavaScriptUtils.showMessageHeaderWarning(BundleUtils.messageBundle("label.atencao"), BundleUtils.messageBundle("message.dataDetailRegisterModeEdition"));
                return;
            }

            this.annotationDynamic = null;
            action = ActionCrudType.CONSULT;
            this.entity = entity;
            eventStartConsult.fire(this);
            modeShowData = true;

            if (processStartEnviroment != null)
                processStartEnviroment.run();

            collapseIn();
        } catch (Exception e) {
            LogUtils.generate(e);
            JavaScriptUtils.showMessageHeaderError(e);
        }
    }

    public void delete(E entity) {
        try {
            if (isModeShowData()) {
                if (action.isDelete())
                    showDataTab();

                JavaScriptUtils.showMessageHeaderWarning(BundleUtils.messageBundle("label.atencao"), BundleUtils.messageBundle("message.dataDetailRegisterModeEdition"));
                return;
            }

            this.annotationDynamic = null;
            action = ActionCrudType.DELETE;
            this.entity = entity;
            eventStartDelete.fire(this);
            modeShowData = true;

            if (processStartEnviroment != null) {
                processStartEnviroment.run();
            }

            collapseIn();
        } catch (Exception e) {
            LogUtils.generate(e);
            JavaScriptUtils.showMessageHeaderError(e);
        }
    }

    public void dynamic(E entity, JArchDynamicDetailShowDataController annotationDynamic) {
        try {
            if (isModeShowData()) {
                if (action.isDynamic())
                    showDataTab();

                JavaScriptUtils.showMessageHeaderWarning(BundleUtils.messageBundle("label.atencao"), BundleUtils.messageBundle("message.dataDetailRegisterModeEdition"));
                return;
            }

            this.annotationDynamic = annotationDynamic;
            action = ActionCrudType.DYNAMIC;
            this.entity = entity;
            eventStartDynamic.fire(this);
            modeShowData = true;

            if (processStartEnviroment != null) {
                processStartEnviroment.run();
            }

            collapseIn();
        } catch (Exception e) {
            LogUtils.generate(e);
            JavaScriptUtils.showMessageHeaderError(e);
        }
    }

    public void cancel() {
        if (action.isChange()) {
            entity = CloneEntityUtils.clone(originalEntity);
            entity.setId(originalEntity.getId());
            rollbackListBeforeChangeToEntityMaster();
            configureDataModel();
        }

        updateDatatableTabBody();

        modeShowData = false;
        required = false;

        try {
            init();

            if (processAfterCancel != null)
                processAfterCancel.accept(entity);
        } catch (InsertException e) {
            LogUtils.generate(e);
        }

        collapse();
    }

    public boolean isBlockedDetail() {
        return blocked
                || (annotationDynamic != null && annotationDynamic.blockedDetail())
                || (!action.isInsert() && !action.isChange() && !action.isClone());
    }

    public void save() {
        try {
            if (action.isInsert()) {
                if (processBeforeSave != null)
                    processBeforeSave.accept(entity);

                saveEntityMasterInDetail();
                validInsert();
            } else if (action.isClone()) {
                if (processBeforeSave != null)
                    processBeforeSave.accept(entity);

                validClone();
            } else if (action.isChange()) {
                if (processBeforeSave != null)
                    processBeforeSave.accept(entity);

                validChange();
            } else {
                if (processBeforeDelete != null)
                    processBeforeDelete.accept(entity);

                validDelete();
            }

            Field fieldCollection = ajustMaster();

            if (action.isInsert() || action.isChange() || action.isClone()) {
                if (processAfterSave != null)
                    processAfterSave.accept(entity);
            } else if (action.isDelete()) {
                if (processAfterDelete != null)
                    processAfterDelete.accept(entity);
            }

            hideDataTab();

            required = false;
            modeShowData = false;

            startEnviroment();

            if (fieldCollection != null)
                configureDataModel();

            updateDatatableTabBody();
        } catch (Exception e) {
            JsfUtils.addMessageError(e);
        }
    }

    public void refresh() {
        startEnviroment();
        createDataModelFromMaster(entityMaster);
        updateDatatableTabBody();
    }

    public void clearDataModel() {
        dataModel = null;
    }

    public Consumer getProcessBeforeSave() {
        return processBeforeSave;
    }

    public void setProcessBeforeSave(Consumer processBeforeSave) {
        this.processBeforeSave = processBeforeSave;
    }

    public Consumer getProcessBeforeDelete() {
        return processBeforeDelete;
    }

    public void setProcessBeforeDelete(Consumer processBeforeDelete) {
        this.processBeforeDelete = processBeforeDelete;
    }

    public Consumer getProcessAfterSave() {
        return processAfterSave;
    }

    public void setProcessAfterSave(Consumer processAfterSave) {
        this.processAfterSave = processAfterSave;
    }

    public Consumer getProcessAfterDelete() {
        return processAfterDelete;
    }

    public void setProcessAfterDelete(Consumer processAfterDelete) {
        this.processAfterDelete = processAfterDelete;
    }

    public Consumer getProcessAfterCancel() {
        return processAfterCancel;
    }

    public void setProcessAfterCancel(Consumer processAfterCancel) {
        this.processAfterCancel = processAfterCancel;
    }

    public Runnable getProcessStartEnviroment() {
        return processStartEnviroment;
    }

    public void setProcessStartEnviroment(Runnable processStartEnviroment) {
        this.processStartEnviroment = processStartEnviroment;
    }

    public List getMenuActions() {
        return acessMenu
                .getMenuActions()
                .stream()
                .sorted(Comparator.comparing(ItemMenuArch::getOrder))
                .collect(Collectors.toList());
    }

    @Override
    public void createMenu(Field field) {
        acessMenu = new AcessMenu(field);
    }

    public JArchDynamicDetailShowDataController getAnnotationDynamic() {
        return annotationDynamic;
    }

    public String getDescriptionDynamic() {
        return annotationDynamic == null
                ? null
                : BundleUtils.messageBundle(annotationDynamic.labelButton());
    }

    public String getStyleClass() {
        return annotationDynamic == null ? null : annotationDynamic.styleClass().getStyleClass();
    }

    public void blocked() {
        this.blocked = true;
    }

    public void setBlocked(boolean blocked) {
        this.blocked = blocked;
    }

    public boolean isBlocked() {
        return blocked;
    }

    public Class[] groupsBeanValidation() {
        return new Class[]{Default.class};
    }

    public void startEnviroment() {
        collapse();
        annotationDynamic = null;
        action = ActionCrudType.CONSULT;
        entity = service.createEntity();
        eventStartConsult.fire(this);
        required = false;
    }

    private void saveEntityMasterInDetail() {
        Field field = ReflectionUtils.getField(entity.getClass(), entityMaster.getClass());

        if (field != null) { // se for BI-DIRECIONAL
            ReflectionUtils.setValue(entity, field, entityMaster);
        }
    }

    private void configureDataModel() {
        List lista = new ArrayList<>();

        Field fieldCollection = ReflectionUtils.getFieldCollection(entityMaster.getClass(), this.entity.getClass());

        if (fieldCollection == null) {
            return;
        }

        Collection listaDetalhe = (Collection) ReflectionUtils.getValueByField(entityMaster, fieldCollection);

        if (listaDetalhe != null) {
            lista.addAll(listaDetalhe);
        }

        if (filterDataModel != null) {
            lista = lista.stream().filter(filterDataModel).collect(Collectors.toList());
        }

        if (orderDataModel != null) {
            lista = lista.stream().sorted(orderDataModel).collect(Collectors.toList());
        }

        dataModel = new br.com.jarch.faces.controller.LazyDataModelPaginator<>(lista, search);
    }

    public void showDataTab() {
        String tabName = getTabName();
        JavaScriptUtils.execute("$('" + tabName + "').collapse('show');");
        collapseIn();
    }

    private static String getTabName() {
        return FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("tabName");
    }

    private void hideDataTab() {
        String tabName = getTabName();
        JavaScriptUtils.execute("$('" + tabName + "').collapse('hide');");
        collapse();
    }

    private void removeEntityFromEntityMaster(E entity) {
        Field field = ReflectionUtils.getFieldCollection(entityMaster.getClass(), entity.getClass());
        ((Collection) ReflectionUtils.getValueByField(entityMaster, field)).removeIf(e -> e.getId() != null && e.getId().equals(entity.getId()));
    }

    private void saveListBeforeChange() {
        Field field = ReflectionUtils.getFieldCollection(entityMaster.getClass(), originalEntity.getClass());
        Collection listMaster = ((Collection) ReflectionUtils.getValueByField(entityMaster, field));
        listBeforeChange = new HashSet<>();
        listMaster.forEach(e -> {
                    E detail = CloneEntityUtils.clone(e);
                    detail.setId(e.getId());
                    listBeforeChange.add(detail);
                }
        );
    }

    private void rollbackListBeforeChangeToEntityMaster() {
        Field field = ReflectionUtils.getFieldCollection(entityMaster.getClass(), originalEntity.getClass());
        Collection listMaster = ((Collection) ReflectionUtils.getValueByField(entityMaster, field));
        listMaster.clear();
        listMaster.addAll(listBeforeChange);
    }

    public boolean isModeShowData() {
        return modeShowData;
    }

    private void updateDatatableTabBody() {
        JavaScriptUtils.execute("if (typeof updateDataTableTabBody == 'function') { updateDataTableTabBody(); }");
        JavaScriptUtils.execute("if (typeof updateDataTableDivDataDetailTab == 'function') { updateDataTableDivDataDetailTab(); }");
    }

    private Field ajustMaster() throws InvocationTargetException, IllegalAccessException {
        Field fieldCollection = ReflectionUtils.getFieldCollection(entityMaster.getClass(), entity.getClass());
        Collection listaDetalhe = null;

        if (fieldCollection == null) {
            Method[] allMethods = entityMaster.getClass().getDeclaredMethods();
            for (Method method : allMethods) {
                if (Collection.class.isAssignableFrom(method.getReturnType())) {
                    ParameterizedType parameterizedType = (ParameterizedType) method.getGenericReturnType();
                    if (parameterizedType == null)
                        continue;

                    Class classGeneric = (Class) parameterizedType.getActualTypeArguments()[0];

                    if (classGeneric == null)
                        continue;

                    if (entity.getClass().isAssignableFrom(classGeneric)) {
                        listaDetalhe = (Collection) ReflectionUtils.executeMethod(entityMaster, method.getName());
                        break;
                    }
                }
            }
        } else
            listaDetalhe = (Collection) ReflectionUtils.getValueByField(entityMaster, fieldCollection);

        if (listaDetalhe == null)
            listaDetalhe = new HashSet<>();

        listaDetalhe.remove(entity);

        if (!action.isDelete())
            listaDetalhe.add(entity);

        if (fieldCollection != null)
            ReflectionUtils.setValue(entityMaster, fieldCollection, listaDetalhe);

        return fieldCollection;
    }

    private void collapse() {
        classCollapse = "collapse";
    }

    private void collapseIn() {
        classCollapse = "collapse in";
    }

    public String getLabelReturn() {
        return BundleUtils.messageBundleParam("label.fechar") + " " + getLabelDataDetail();
    }

    public String getLabelCancel() {
        return BundleUtils.messageBundle("label.cancelar") + " " + getLabelDataDetail();
    }

    public String getLabelSave() {
        return BundleUtils.messageBundle("label.salvar") + " " + getLabelDataDetail();
    }

    public String getLabelDelete() {
        return BundleUtils.messageBundle("label.excluir") + " " + getLabelDataDetail();
    }

    private String getLabelDataDetail() {
        String label = getEntity().getClass().getSimpleName();
        label = label.substring(0, 1).toLowerCase() + label.substring(1);
        label = label.replace("Entity", "");
        label = "label." + label;
        return BundleUtils.messageBundle(label);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy