org.sakaiproject.sitestats.tool.wicket.components.paging.infinite.InfinitePagingDataTable.java Source code

Java tutorial

Introduction

Here is the source code for org.sakaiproject.sitestats.tool.wicket.components.paging.infinite.InfinitePagingDataTable.java

Source

/**
 * Copyright (c) 2006-2019 The Apereo Foundation
 *
 * Licensed under the Educational Community 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://opensource.org/licenses/ecl2
 *
 * 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.
 */
// Adapted from https://github.com/apache/wicket/blob/wicket-6.x/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/repeater/data/table/DataTable.java

package org.sakaiproject.sitestats.tool.wicket.components.paging.infinite;

import java.util.List;

import lombok.Getter;

import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.behavior.Behavior;
import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
import org.apache.wicket.extensions.markup.html.repeater.data.table.IStyledColumn;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.markup.repeater.IItemReuseStrategy;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.RepeatingView;
import org.apache.wicket.model.IModel;
import org.apache.wicket.util.lang.Args;
import org.apache.wicket.util.string.Strings;
import org.apache.wicket.util.visit.IVisit;
import org.apache.wicket.util.visit.IVisitor;

import org.sakaiproject.sitestats.tool.wicket.providers.infinite.InfiniteDataProvider;

/**
 * A DataTable that can page its contents without knowing how many total rows there will be. Based in part on the code
 * for Wicket's DataTable class.
 * @author plukasew
 * @param <T> model type
 * @param <S> sort type
 */
public class InfinitePagingDataTable<T, S> extends Panel {
    static abstract class CssAttributeBehavior extends Behavior {
        private static final long serialVersionUID = 1L;

        protected abstract String getCssClass();

        @Override
        public void onComponentTag(final Component component, final ComponentTag tag) {
            String className = getCssClass();
            if (!Strings.isEmpty(className)) {
                tag.append("class", className, " ");
            }
        }
    }

    @Getter
    private final WebMarkupContainer body;
    private final List<? extends IColumn<T, S>> columns;
    @Getter
    private final ToolbarsContainer topToolbars;
    @Getter
    private final ToolbarsContainer bottomToolbars;
    @Getter
    private final Caption caption;
    private long toolbarIdCounter;

    private final InfinitePagingDataGridView<T> datagrid;

    public InfinitePagingDataTable(String id, final List<? extends IColumn<T, S>> columns,
            final InfiniteDataProvider<T> dataProvider, final long rowsPerPage) {
        super(id);

        Args.notEmpty(columns, "columns");

        this.columns = columns;
        this.caption = new Caption("caption", getCaptionModel());
        add(caption);
        body = newBodyContainer("body");
        datagrid = newInfinitePagingDataGridView("rows", columns, dataProvider);
        datagrid.setItemsPerPage(rowsPerPage);
        body.add(datagrid);
        add(body);
        topToolbars = new ToolbarsContainer("topToolbars");
        bottomToolbars = new ToolbarsContainer("bottomToolbars");
        add(topToolbars);
        add(bottomToolbars);
    }

    @Override
    public void onInitialize() {
        super.onInitialize();

    }

    protected InfinitePagingDataGridView<T> newInfinitePagingDataGridView(String id,
            List<? extends IColumn<T, S>> columns, InfiniteDataProvider<T> dataProvider) {
        return new DefaultInfinitePagingDataGridView(id, columns, dataProvider);
    }

    protected IModel<String> getCaptionModel() {
        return null;
    }

    protected WebMarkupContainer newBodyContainer(final String id) {
        return new WebMarkupContainer(id);
    }

    public final void setTableBodyCss(final String cssStyle) {
        body.add(AttributeModifier.replace("class", cssStyle));
    }

    public void addBottomToolbar(final InfinitePagingDataTableToolbar toolbar) {
        addToolbar(toolbar, bottomToolbars);
    }

    public void addTopToolbar(final InfinitePagingDataTableToolbar toolbar) {
        addToolbar(toolbar, topToolbars);
    }

    public final InfiniteDataProvider<T> getDataProvider() {
        return datagrid.getDataProvider();
    }

    public final List<? extends IColumn<T, S>> getColumns() {
        return columns;
    }

    public final void nextPage() {
        datagrid.nextPage();
    }

    public final void prevPage() {
        datagrid.prevPage();
    }

    public final boolean hasNextPage() {
        return datagrid.hasNextPage();
    }

    public final boolean hasPrevPage() {
        return datagrid.hasPrevPage();
    }

    public final long getItemsPerPage() {
        return datagrid.getItemsPerPage();
    }

    public final void setOffset(long value) {
        datagrid.setOffset(value);
    }

    public final long getOffset() {
        return datagrid.getOffset();
    }

    public final int getRowCount() {
        return datagrid.getRowCount();
    }

    public final InfinitePagingDataTable<T, S> setItemReuseStrategy(final IItemReuseStrategy strategy) {
        datagrid.setItemReuseStrategy(strategy);
        return this;
    }

    public void setItemsPerPage(final long items) {
        datagrid.setItemsPerPage(items);
    }

    private void addToolbar(final InfinitePagingDataTableToolbar toolbar, final ToolbarsContainer container) {
        Args.notNull(toolbar, "toolbar");
        container.getRepeatingView().add(toolbar);
    }

    protected Item<IColumn<T, S>> newCellItem(final String id, final int index, final IModel<IColumn<T, S>> model) {
        return new Item<>(id, index, model);
    }

    protected Item<T> newRowItem(final String id, final int index, final IModel<T> model) {
        return new Item<>(id, index, model);
    }

    @Override
    protected void onDetach() {
        super.onDetach();

        for (IColumn<T, S> column : columns) {
            column.detach();
        }
    }

    protected void onPageChanged() {
        // noop
    }

    protected String newToolbarId() {
        toolbarIdCounter++;
        return String.valueOf(toolbarIdCounter).intern();
    }

    @Override
    protected void onComponentTag(ComponentTag tag) {
        checkComponentTag(tag, "table");
        super.onComponentTag(tag);
    }

    /**
     * This class acts as a repeater that will contain the toolbar. It makes sure that the table row
     * group (e.g. thead) tags are only visible when they contain rows in accordance with the HTML
     * specification.
     */
    private static class ToolbarsContainer extends WebMarkupContainer {
        private static final long serialVersionUID = 1L;

        private final RepeatingView toolbars;

        /**
         * Constructor
         *
         * @param id
         */
        private ToolbarsContainer(final String id) {
            super(id);
            toolbars = new RepeatingView("toolbars");
            add(toolbars);
        }

        public RepeatingView getRepeatingView() {
            return toolbars;
        }

        @Override
        public void onConfigure() {
            super.onConfigure();
            toolbars.configure();

            Boolean visible = toolbars.visitChildren(new IVisitor<Component, Boolean>() {
                @Override
                public void component(Component object, IVisit<Boolean> visit) {
                    object.configure();
                    if (object.isVisible()) {
                        visit.stop(Boolean.TRUE);
                    } else {
                        visit.dontGoDeeper();
                    }
                }
            });

            if (visible == null) {
                visible = false;
            }

            setVisible(visible);
        }
    }

    /**
     * A caption for the table. It renders itself only if getCaptionModel() has
     * non-empty value.
     */
    private static class Caption extends Label {
        private static final long serialVersionUID = 1L;

        /**
         * Construct.
         *
         * @param id
         *            the component id
         * @param model
         *            the caption model
         */
        public Caption(String id, IModel<String> model) {
            super(id, model);
        }

        @Override
        protected void onConfigure() {
            setRenderBodyOnly(Strings.isEmpty(getDefaultModelObjectAsString()));
            super.onConfigure();
        }

        @Override
        protected IModel<String> initModel() {
            // don't try to find the model in the parent
            return null;
        }
    }

    private class DefaultInfinitePagingDataGridView extends InfinitePagingDataGridView<T> {
        public DefaultInfinitePagingDataGridView(String id, List<? extends IColumn<T, S>> columns,
                InfiniteDataProvider<T> dataProvider) {
            super(id, columns, dataProvider);
        }

        @Override
        protected Item newCellItem(final String id, final int index, final IModel model) {
            Item item = InfinitePagingDataTable.this.newCellItem(id, index, model);
            final IColumn<T, S> column = InfinitePagingDataTable.this.columns.get(index);
            if (column instanceof IStyledColumn) {
                item.add(new CssAttributeBehavior() {
                    private static final long serialVersionUID = 1L;

                    @Override
                    protected String getCssClass() {
                        return ((IStyledColumn<T, S>) column).getCssClass();
                    }
                });
            }

            return item;
        }

        @Override
        protected Item<T> newRowItem(final String id, final int index, final IModel<T> model) {
            return InfinitePagingDataTable.this.newRowItem(id, index, model);
        }
    }
}