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

tools.dynamia.zk.viewers.table.TableView Maven / Gradle / Ivy

/*
 * Copyright (C) 2023 Dynamia Soluciones IT S.A.S - NIT 900302344-1
 * Colombia / South America
 *
 * 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 tools.dynamia.zk.viewers.table;

import org.zkoss.bind.Binder;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zul.AbstractListModel;
import org.zkoss.zul.ListModel;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Listfoot;
import org.zkoss.zul.Listhead;
import org.zkoss.zul.Listitem;
import org.zkoss.zul.ListitemRenderer;
import org.zkoss.zul.Menupopup;
import tools.dynamia.commons.MapBuilder;
import tools.dynamia.commons.PropertyChangeListenerContainer;
import tools.dynamia.commons.collect.PagedList;
import tools.dynamia.domain.fx.Functions;
import tools.dynamia.domain.fx.MultiFunctionProcessor;
import tools.dynamia.domain.query.DataSet;
import tools.dynamia.viewers.TableViewComponent;
import tools.dynamia.viewers.View;
import tools.dynamia.viewers.ViewDescriptor;
import tools.dynamia.viewers.util.Viewers;
import tools.dynamia.zk.BindingComponentIndex;
import tools.dynamia.zk.ComponentAliasIndex;
import tools.dynamia.zk.ui.CanBeReadonly;
import tools.dynamia.zk.util.ZKBindingUtil;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.function.Consumer;

/**
 * @author Mario A. Serrano Leones
 */
@SuppressWarnings("unchecked")
public class TableView extends Listbox implements TableViewComponent, CanBeReadonly {

    static {
        BindingComponentIndex.getInstance().put("value", TableView.class);
        ComponentAliasIndex.getInstance().add(TableView.class);
    }

    /**
     *
     */
    private static final long serialVersionUID = 1L;
    /**
     * Event to listen double click events in ListItmes
     */
    public static final String ON_ITEM_DOUBLE_CLICK = "onItemDoubleClick";
    public static final String ON_ITEM_CLICK = "onItemDoubleClick";
    public static final String ON_ITEMS_RENDERED = "onItemsRendered";
    public static final String ON_VALUE_CHANGED = "onValueChanged";
    public static final String ON_MODEL_CHANGED = "onModelChanged";
    private List value;
    private ViewDescriptor viewDescriptor;

    private boolean showRowNumber = true;
    private List defaultValue;
    private View parentView;
    private String orderBy;
    private int maxResults;
    private Menupopup contextMenu;
    private Object source;
    private Consumer onSourceChange;
    private boolean projection;
    private PagedList pageList;
    private boolean readonly;
    private List footersWithFunctions;
    private MultiFunctionProcessor multiFunctionProcesor;


    public TableView() {

    }

    public TableView(ViewDescriptor viewDescriptor) {
        this.viewDescriptor = viewDescriptor;
    }

    public int getAbsoluteIndex(Listitem item) {
        int ai = item.getIndex() + 1;
        if (pageList != null) {
            int pai = getPaginal().getPageSize() * getPaginal().getActivePage();
            ai += pai;
        }

        return ai;
    }

    @Override
    public List getValue() {
        return value;
    }

    @Override
    public void setValue(DataSet> dataSet) {
        setValue(dataSet.getData());
    }

    @Override
    public void setValue(List value) {
        if (value instanceof PagedList) {
            this.pageList = (PagedList) value;
            //  value = this.pageList.getDataSource().getPageData();
        } else {
            this.pageList = null;
        }


        boolean changed = false;
        if (defaultValue != null && !defaultValue.isEmpty()) {
            this.value = new ArrayList<>(defaultValue);
            if (value != null) {
                this.value.addAll(value);
                changed = true;
            }
        } else {
            try {
                if ((this.value == null && value != null) || (this.value != null && value == null) ||
                        (this.value != null && value != null && this.value.size() != value.size()) || this.value != value) {
                    changed = true;
                }
            } catch (NoSuchElementException e) {
                changed = true;
            }
            this.value = value;
        }


        if (this.value == null) {
            setModel((ListModel) null);
        } else {
            setModel(new TableViewModel<>(this.value, true, isMultiple()));
        }

        if (changed) {
            Events.postEvent(ON_VALUE_CHANGED, this, this.value);
        }
    }

    @Override
    public T getSelected() {
        if (getSelectedItem() != null) {
            return getSelectedItem().getValue();
        } else {
            return null;
        }
    }

    @Override
    public void setSelected(Object selected) {
        if (selected != null && getModel() instanceof AbstractListModel model) {
            model.addToSelection(selected);
        }
    }


    public void setDefaultValue(List defaultValue) {
        this.defaultValue = defaultValue;
    }

    @Override
    public TableFieldComponent getTableFieldComponent(String fieldName, int rowIndex) {
        try {
            Listitem item = getItemAtIndex(rowIndex);
            Map tfcMap = (Map) item
                    .getAttribute("TABLE_FIELD_COMPONENTS");
            return tfcMap.get(fieldName);
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public TableFieldComponent getTableFieldComponent(String fieldName, Object item) {
        try {
            if (item instanceof Component component) {
                Map tfcMap = (Map) component
                        .getAttribute("TABLE_FIELD_COMPONENTS");
                return tfcMap.get(fieldName);
            }
        } catch (Exception e) {
            return null;
        }
        return null;
    }

    @Override
    public void clear() {
        setValue((List) null);
    }

    public Listitem getListItemByValue(T value) {
        Listitem target = null;
        for (Object obj : getItems()) {
            Listitem item = (Listitem) obj;
            if (item.getValue().equals(value)) {
                target = item;
                break;
            }
        }
        return target;
    }

    @Override
    public ViewDescriptor getViewDescriptor() {
        return viewDescriptor;
    }

    @Override
    public void setViewDescriptor(ViewDescriptor viewDescriptor) {
        this.viewDescriptor = viewDescriptor;
    }

    @Override
    public void setItemRenderer(ListitemRenderer renderer) {
        super.setItemRenderer(renderer);
        if (renderer instanceof TableViewRowRenderer tvrr) {
            tvrr.setViewDescriptor(viewDescriptor);
            tvrr.setTableView(this);
        }
    }

    @Override
    public void setShowRowNumber(boolean showRowNumber) {
        this.showRowNumber = showRowNumber;
    }

    @Override
    public boolean isShowRowNumber() {
        return showRowNumber;
    }

    @Override
    public boolean isListitemSelected() {
        return getSelectedItem() != null;
    }

    @Override
    public View getParentView() {
        return parentView;
    }

    @Override
    public void setParentView(View parentView) {
        this.parentView = parentView;
    }

    public String getOrderBy() {
        return orderBy;
    }

    public void setOrderBy(String orderBy) {
        this.orderBy = orderBy;
    }

    public Menupopup getContextMenu() {
        return contextMenu;
    }

    public void setContextMenu(Menupopup contextMenu) {
        this.contextMenu = contextMenu;
    }

    @Override
    public TableViewFooter getFooter(String fieldName) {
        Listfoot foot = getListfoot();
        if (foot != null) {
            List footers = foot.getChildren();
            for (TableViewFooter listfooter : footers) {
                Object fn = listfooter.getAttribute("field-name");
                if (fn != null && fn.toString().equals(fieldName)) {
                    return listfooter;
                }
            }
        }
        return null;
    }

    @Override
    public TableViewHeader getHeader(String fieldName) {
        Listhead head = getListhead();
        if (head != null) {
            List headers = head.getChildren();
            for (TableViewHeader header : headers) {
                Object fn = header.getAttribute("field-name");
                if (fn != null && fn.toString().equals(fieldName)) {
                    return header;
                }
            }
        }
        return null;
    }

    public void updateUI() {
        Events.postEvent(ON_MODEL_CHANGED, this, this.value);

        Events.postEvent(ON_VALUE_CHANGED, this, this.value);

    }

    @Override
    public boolean isEmpty() {
        return getModel() == null || getModel().getSize() == 0;
    }

    @Override
    public Object getSource() {
        return source;
    }

    @Override
    public void setSource(Object source) {
        this.source = source;
        if (onSourceChange != null) {
            onSourceChange.accept(source);
        }

        if (source instanceof PropertyChangeListenerContainer) {
            ((PropertyChangeListenerContainer) source).addPropertyChangeListener(l -> computeFooters());
        }
    }

    public int getMaxResults() {
        return maxResults;
    }

    public void setMaxResults(int maxResults) {
        this.maxResults = maxResults;
    }

    public boolean isProjection() {
        return projection;
    }

    public void setProjection(boolean projection) {
        this.projection = projection;
    }

    @Override
    public boolean isReadonly() {
        return readonly;
    }

    @Override
    public void setReadonly(boolean readonly) {
        boolean old = this.readonly;
        this.readonly = readonly;

        if (old != this.readonly) {
            renderAll();
        }

    }

    /**
     * Reload component binding for selected row
     */
    public void updateSelectedItem() {
        try {
            var selectRow = getSelectedItem();
            var binder = (Binder) selectRow.getAttribute(TableViewRowRenderer.ROW_BINDER_NAME);
            ZKBindingUtil.bindBean(selectRow, Viewers.BEAN, selectRow.getValue());
            binder.loadComponent(selectRow, false);
        } catch (Exception e) {
            //cannot doit
        }
    }

    public void onSourceChanged(Consumer onSourceChange) {
        this.onSourceChange = onSourceChange;
    }

    void setFootersWithFunctions(List footersWithFunctions) {
        this.footersWithFunctions = footersWithFunctions;
    }

    List getFootersWithFunctions() {
        return footersWithFunctions;
    }

    /**
     * Update all footer with functions
     */
    public void computeFooters() {
        try {
            if (footersWithFunctions != null) {
                footersWithFunctions.forEach(TableViewFooter::clear);

                if (value != null) {
                    if (multiFunctionProcesor != null) {
                        var result = multiFunctionProcesor.compute(value, new HashMap<>(), footersWithFunctions);
                        result.forEach((f, v) -> footersWithFunctions.stream()
                                .filter(ft -> ft.equals(f)).findFirst()
                                .ifPresent(tableViewFooter -> tableViewFooter.setValue(v)));
                    } else {
                        footersWithFunctions.forEach(footer -> {
                            if (value instanceof Collection) {
                                if (!((Collection) value).isEmpty()) {
                                    Map args = MapBuilder.put("property", footer.getField().getName());
                                    Object result = Functions.compute(footer.getFunction(), value, args);
                                    footer.setValue(result);
                                }
                            }
                        });
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void setMultiFunctionProcesor(MultiFunctionProcessor multiFunctionProcesor) {
        this.multiFunctionProcesor = multiFunctionProcesor;
    }

    public MultiFunctionProcessor getMultiFunctionProcesor() {
        return multiFunctionProcesor;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy