ro.fortsoft.wicket.pivot.web.PivotTable.java Source code

Java tutorial

Introduction

Here is the source code for ro.fortsoft.wicket.pivot.web.PivotTable.java

Source

/*
 * Copyright 2012 Decebal Suiu
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with
 * the License. You may obtain a copy of the License in the LICENSE file, or 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 ro.fortsoft.wicket.pivot.web;

import java.io.Serializable;

import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.GenericPanel;
import org.apache.wicket.markup.repeater.RepeatingView;
import org.apache.wicket.model.Model;
import org.apache.wicket.util.convert.IConverter;

import ro.fortsoft.wicket.pivot.PivotField;
import ro.fortsoft.wicket.pivot.PivotModel;
import ro.fortsoft.wicket.pivot.PivotTableRenderModel;
import ro.fortsoft.wicket.pivot.PivotTableRenderModel.DataHeaderRenderCell;
import ro.fortsoft.wicket.pivot.PivotTableRenderModel.DataRenderRow;
import ro.fortsoft.wicket.pivot.PivotTableRenderModel.DataValueRenderCell;
import ro.fortsoft.wicket.pivot.PivotTableRenderModel.GrandTotalHeaderRenderCell;
import ro.fortsoft.wicket.pivot.PivotTableRenderModel.GrandTotalRenderRow;
import ro.fortsoft.wicket.pivot.PivotTableRenderModel.GrandTotalRowHeaderRenderCell;
import ro.fortsoft.wicket.pivot.PivotTableRenderModel.GrandTotalValueRenderCell;
import ro.fortsoft.wicket.pivot.PivotTableRenderModel.HeaderRenderCell;
import ro.fortsoft.wicket.pivot.PivotTableRenderModel.HeaderRenderRow;
import ro.fortsoft.wicket.pivot.PivotTableRenderModel.HeaderValueRenderCell;
import ro.fortsoft.wicket.pivot.PivotTableRenderModel.RenderCell;

/**
 * @author Decebal Suiu
 */
public class PivotTable extends GenericPanel<PivotModel> {

    private static final long serialVersionUID = 1L;

    public PivotTable(String id, PivotModel pivotModel) {
        super(id, Model.of(pivotModel));
    }

    private Component applyRowColSpan(RenderCell cell, Component tmp) {
        if (cell.getColspan() > 1)
            tmp.add(AttributeModifier.append("colspan", cell.getColspan()));
        if (cell.getRowspan() > 1)
            tmp.add(AttributeModifier.append("rowspan", cell.getRowspan()));
        return tmp;
    }

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

        PivotModel pivotModel = getModelObject();
        PivotTableRenderModel renderModel = PivotTableRenderModel.create(pivotModel);

        // rendering header
        RepeatingView column = new RepeatingView("header");
        add(column);

        Component tmp = null;
        for (HeaderRenderRow row : renderModel.getHeaderRows()) {
            // rendering row header (first columns)
            WebMarkupContainer tr = new WebMarkupContainer(column.newChildId());
            column.add(tr);
            RepeatingView rowHeader = new RepeatingView("rowHeader");
            tr.add(rowHeader);

            for (HeaderRenderCell cell : row.getRowHeader()) {
                if (cell.getPivotField() == null) {
                    // rendering an empty cell
                    tmp = new Label(rowHeader.newChildId(), "");
                    tmp.add(AttributeModifier.append("class", "empty"));
                    applyRowColSpan(cell, tmp);
                    rowHeader.add(tmp);
                } else {
                    // rendering row field
                    tmp = createTitleLabel(rowHeader.newChildId(), cell.getPivotField());
                    applyRowColSpan(cell, tmp);
                    rowHeader.add(tmp);
                }
            }

            // rendering column keys
            RepeatingView value = new RepeatingView("value");
            tr.add(value);
            for (RenderCell cell : row.getValueCells()) {
                if (cell instanceof HeaderValueRenderCell) {
                    HeaderValueRenderCell headerValueRenderCell = (HeaderValueRenderCell) cell;
                    tmp = createValueLabel(value.newChildId(), headerValueRenderCell.getRawValue(),
                            headerValueRenderCell.getPivotField());
                    applyRowColSpan(cell, tmp);
                    value.add(tmp);
                } else {
                    HeaderRenderCell headerRenderCell = (HeaderRenderCell) cell;
                    tmp = createTitleLabel(value.newChildId(), headerRenderCell.getPivotField());
                    applyRowColSpan(cell, tmp);
                    value.add(tmp);
                }
            }

            // rendering grand total column
            RepeatingView grandTotalColumn = new RepeatingView("grandTotalColumn");
            for (RenderCell cell : row.getGrandTotalColumn()) {
                if (cell instanceof GrandTotalHeaderRenderCell) {
                    GrandTotalHeaderRenderCell grandTotalHeaderRenderCell = (GrandTotalHeaderRenderCell) cell;
                    if (grandTotalHeaderRenderCell.getRawValue() != null) {
                        tmp = new Label(grandTotalColumn.newChildId(),
                                grandTotalHeaderRenderCell.getRawValue().toString());
                        applyRowColSpan(cell, tmp);
                        grandTotalColumn.add(tmp);
                    } else {
                        tmp = new WebMarkupContainer(grandTotalColumn.newChildId());
                        applyRowColSpan(cell, tmp);
                        tmp.add(AttributeModifier.append("class", "empty"));
                        grandTotalColumn.add(tmp);
                    }
                } else {
                    HeaderRenderCell headerCell = (HeaderRenderCell) cell;
                    tmp = createTitleLabel(value.newChildId(), headerCell.getPivotField());
                    applyRowColSpan(cell, tmp);
                    grandTotalColumn.add(tmp);
                }
            }
            grandTotalColumn.setVisible(row.getGrandTotalColumn().size() > 0);
            tr.add(grandTotalColumn);
        }

        // rendering rows
        RepeatingView row = new RepeatingView("row");
        add(row);
        for (DataRenderRow renderRow : renderModel.getValueRows()) {
            WebMarkupContainer tr = new WebMarkupContainer(row.newChildId());
            row.add(tr);
            RepeatingView rowHeader = new RepeatingView("rowHeader");
            tr.add(rowHeader);

            for (DataHeaderRenderCell cell : renderRow.getRowHeader()) {
                tmp = createValueLabel(rowHeader.newChildId(), cell.getRawValue(), cell.getPivotField());
                applyRowColSpan(cell, tmp);
                rowHeader.add(tmp);
            }

            RepeatingView value = new RepeatingView("value");
            tr.add(value);

            for (RenderCell cell : renderRow.getValue()) {
                if (cell instanceof DataValueRenderCell) {
                    tmp = createValueLabel(value.newChildId(), cell.getRawValue(), cell.getPivotField());
                    applyRowColSpan(cell, tmp);
                    value.add(tmp);
                } else {
                    GrandTotalValueRenderCell grandTotalCell = (GrandTotalValueRenderCell) cell;
                    tmp = createGrandTotalLabel(value.newChildId(), grandTotalCell.getRawValue(),
                            grandTotalCell.isForRow());
                    applyRowColSpan(cell, tmp);
                    tmp.add(AttributeModifier.append("class", "grand-total"));
                    value.add(tmp);
                }
            }
        }

        WebMarkupContainer grandTotalRow = new WebMarkupContainer("grandTotalRow");
        grandTotalRow.setVisible(renderModel.getGrandTotalRows().size() > 0);
        add(grandTotalRow);
        /*
         * We currently expect exactly one GrantTotalRenderRow, therefor we dont
         * need a repeating viewer
         */
        for (GrandTotalRenderRow grantTotalRenderRow : renderModel.getGrandTotalRows()) {
            for (GrandTotalRowHeaderRenderCell cell : grantTotalRenderRow.getRowHeader()) {
                Label grandTotalRowHeader = new Label("rowHeader", "Grand Total");
                applyRowColSpan(cell, grandTotalRowHeader);
                grandTotalRow.add(grandTotalRowHeader);
            }

            RepeatingView value = new RepeatingView("value");
            grandTotalRow.add(value);
            for (GrandTotalValueRenderCell cell : grantTotalRenderRow.getValue()) {
                tmp = createGrandTotalLabel(value.newChildId(), cell.getRawValue(), cell.isForRow());
                value.add(tmp);
            }
        }
    }

    /**
     * Retrieves a name that display the pivot table title (for fields on ROW
     * and DATA areas)
     */
    protected Label createTitleLabel(String id, PivotField pivotField) {
        String title = pivotField.getTitle();
        if (pivotField.getArea().equals(PivotField.Area.DATA)) {
            title += " (" + pivotField.getCalculationDescription() + ")";
        }

        return new Label(id, title);
    }

    protected Label createValueLabel(String id, Object value, final PivotField pivotField) {
        return new Label(id, Model.of((Serializable) value)) {
            private static final long serialVersionUID = 1L;

            @SuppressWarnings("unchecked")
            @Override
            public <C> IConverter<C> getConverter(Class<C> type) {
                IConverter<C> converter = (IConverter<C>) pivotField.getConverter();
                if (converter != null) {
                    return converter;
                }

                return super.getConverter(type);
            }

        };
    }

    protected Label createGrandTotalLabel(String id, Object value, boolean forRow) {
        return new Label(id, Model.of((Serializable) value));
    }
}