Package org.openfaces.renderkit.table

Source Code of org.openfaces.renderkit.table.TableHeaderOrFooter

/*
* OpenFaces - JSF Component Library 2.0
* Copyright (C) 2007-2012, TeamDev Ltd.
* licensing@openfaces.org
* Unless agreed in writing the contents of this file are subject to
* the GNU Lesser General Public License Version 2.1 (the "LGPL" License).
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* Please visit http://openfaces.org/licensing/ for more details.
*/
package org.openfaces.renderkit.table;

import org.openfaces.component.TableStyles;
import org.openfaces.component.table.AbstractTable;
import org.openfaces.component.table.BaseColumn;
import org.openfaces.component.table.impl.DynamicCol;
import org.openfaces.component.table.Scrolling;
import org.openfaces.org.json.JSONException;
import org.openfaces.org.json.JSONObject;
import org.openfaces.renderkit.TableUtil;
import org.openfaces.util.Rendering;
import org.openfaces.util.StyleGroup;
import org.openfaces.util.Styles;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
* @author Dmitry Pikhulya
*/
public abstract class TableHeaderOrFooter extends TableSection {
    private static final String DEFAULT_SUBHEADER_ROW_CELLS_CLASS = "o_filter_row_cells";

    private boolean isHeader;

    private HeaderRow commonHeaderRow;
    private List<HeaderRow> allRows;
    private boolean hasSubHeader;
    private int lastVisibleColHeadersRow = -1;
    private Boolean ieDocModeAdditionalSupport;

    protected TableHeaderOrFooter(TableStructure tableStructure, boolean composeHeader) {
        super(tableStructure);
        isHeader = composeHeader;

        boolean applyDefaultStyle = tableStructure.getTableStyles().getApplyDefaultStyle();
        String cellTag = isHeader
                ? (applyDefaultStyle ? "td" : "th")
                : "td";

        allRows = new ArrayList<HeaderRow>();
        List<BaseColumn> columns = tableStructure.getColumns();
        commonHeaderRow = composeCommonHeaderRow(tableStructure, cellTag);
        if (tableStructure.getScrolling() == null) {
            composeNonScrollingContent(cellTag, columns);
        } else {
            composeScrollingContent(tableStructure, cellTag, columns);
        }
    }

    private void composeScrollingContent(TableStructure tableStructure, String cellTag, List<BaseColumn> columns) {
        List<HeaderCell> cells = new ArrayList<HeaderCell>();
        int leftFixedCols = tableStructure.getLeftFixedCols();
        int rightFixedCols = tableStructure.getRightFixedCols();
        int totalColCount = columns.size();

        if (leftFixedCols > 0)
            cells.add(scrollingAreaCell(tableStructure, cellTag, columns, 0, leftFixedCols, false));

        cells.add(scrollingAreaCell(tableStructure, cellTag, columns, leftFixedCols, totalColCount - rightFixedCols, true));

        if (rightFixedCols > 0)
            cells.add(scrollingAreaCell(tableStructure, cellTag, columns, totalColCount - rightFixedCols, totalColCount, false));

        boolean contentsSpecified = false;
        TableScrollingArea firstArea = (TableScrollingArea) cells.get(0).getContent();
        for (int rowIndex = 0, rowCount = firstArea.getRows().size(); rowIndex < rowCount; rowIndex++) {
            boolean rowContentSpecified = false;
            for (HeaderCell areaCell : cells) {
                TableScrollingArea area = (TableScrollingArea) areaCell.getContent();
                if (area.getRows().get(rowIndex).isAtLeastOneComponentInThisRow()) {
                    rowContentSpecified = true;
                    contentsSpecified = true;
                    break;
                }
            }
            for (HeaderCell areaCell : cells) {
                TableScrollingArea area = (TableScrollingArea) areaCell.getContent();
                ((HeaderRow) area.getRows().get(rowIndex)).setAtLeastOneComponentInThisRow(rowContentSpecified);
            }
        }
        if (contentsSpecified)
            allRows.add(new HeaderRow(this, true, cells));
        if (commonHeaderRow != null)
            allRows.add(isHeader ? 0 : allRows.size(), commonHeaderRow);
    }

    private HeaderCell scrollingAreaCell(
            TableStructure tableStructure,
            String cellTag,
            List<BaseColumn> columns,
            int startColIndex, int endColIndex,
            boolean scrollable
    ) {
        List<HeaderRow> rows = composeColumnHeaderRows(columns, startColIndex, endColIndex, cellTag);
        for (int i = 0; i < rows.size(); i++) {
            HeaderRow row = rows.get(i);
            if (row.isAtLeastOneComponentInThisRow())
                lastVisibleColHeadersRow = i;
        }
        HeaderRow subHeaderRow = composeSubHeaderRow(columns.subList(startColIndex, endColIndex), cellTag);
        if (subHeaderRow != null) {
            rows.add(isHeader ? rows.size() : 0, subHeaderRow);
            hasSubHeader = true;
        }

        TableScrollingArea tableScrollingArea = new TableScrollingArea(
                this, columns.subList(startColIndex, endColIndex), rows,
                scrollable ? TableScrollingArea.ScrollingType.HORIZONTAL : TableScrollingArea.ScrollingType.NONE,isHeader && getIeDocModeAdditionalSupportNeeded());
        tableScrollingArea.setCellpadding(tableStructure.getTableCellPadding());
        return new HeaderCell(null, tableScrollingArea, "td", null);
    }

    private Boolean getIeDocModeAdditionalSupportNeeded(){
        if (ieDocModeAdditionalSupport == null){
            String  paramValue = FacesContext.getCurrentInstance().getExternalContext().getInitParameter(TableStructure.INIT_PARAM_ADDITIONAL_IEDOCMODE7_SUPPORT);
            if  (paramValue != null){
                ieDocModeAdditionalSupport = Boolean.valueOf(paramValue);
            }else{
                ieDocModeAdditionalSupport = Boolean.FALSE;
            }
        }
        return ieDocModeAdditionalSupport;
    }

    private void composeNonScrollingContent(String cellTag, List<BaseColumn> columns) {
        List<HeaderRow> columnHeaderRows = composeColumnHeaderRows(columns, 0, columns.size(), cellTag);
        for (int i = 0; i < columnHeaderRows.size(); i++) {
            HeaderRow row = columnHeaderRows.get(i);
            if (row.isAtLeastOneComponentInThisRow())
                lastVisibleColHeadersRow = i;
        }
        HeaderRow subHeaderRow = composeSubHeaderRow(columns, "td");
        hasSubHeader = subHeaderRow != null;
        if (!isHeader) {
            if (subHeaderRow != null)
                allRows.add(subHeaderRow);
        } else {
            if (commonHeaderRow != null)
                allRows.add(commonHeaderRow);
        }

        for (HeaderRow row : columnHeaderRows) {
            allRows.add(row);
        }

        if (isHeader) {
            if (subHeaderRow != null)
                allRows.add(subHeaderRow);
        } else {
            if (commonHeaderRow != null)
                allRows.add(commonHeaderRow);
        }
    }

    public static int composeColumnHierarchies(
            List<BaseColumn> columns,
            List<BaseColumn>[] columnHierarchies,
            boolean isHeader,
            boolean skipEmptyHeaders) {
        int columnHierarchyLevels = 0;
        for (int colIndex = 0, colCount = columns.size(); colIndex < colCount; colIndex++) {
            List<BaseColumn> columnHierarchy = new ArrayList<BaseColumn>();
            BaseColumn startingColumn = columns.get(colIndex);
            for (BaseColumn column = startingColumn;
                 column != null;
                 column = column.getParent() instanceof BaseColumn ? (BaseColumn) column.getParent() : null) {
                if (skipEmptyHeaders && column != startingColumn) {
                    Object header = getHeaderOrFooterCellContent(column, isHeader);
                    if (header == null)
                        continue;
                }
                columnHierarchy.add(0, column);
            }
            columnHierarchies[colIndex] = columnHierarchy;
            columnHierarchyLevels = Math.max(columnHierarchyLevels, columnHierarchy.size());
        }
        return columnHierarchyLevels;
    }

    private HeaderRow composeCommonHeaderRow(TableStructure tableStructure, String cellTag) {
        List columns = tableStructure.getColumns();
        TableStyles table = tableStructure.getTableStyles();
        UIComponent headerOrFooter = isHeader ? table.getHeader() : table.getFooter();
        if (headerOrFooter == null)
            return null;
        HeaderCell cell = new HeaderCell(null, headerOrFooter, cellTag, null);

        int colSpan;
        Scrolling scrolling = tableStructure.getScrolling();
        if (scrolling == null)
            colSpan = columns.size();
        else {
            colSpan = 1;
            if (tableStructure.getLeftFixedCols() > 0)
                colSpan++;
            if (tableStructure.getRightFixedCols() > 0)
                colSpan++;
        }
        cell.setSpans(colSpan, 0, 0);
        return new HeaderRow(this, true, Collections.singletonList(cell));
    }

    private HeaderRow composeSubHeaderRow(List<BaseColumn> columns, String cellTag) {
        boolean atLeastOneComponent = false;
        List<HeaderCell> cells = new ArrayList<HeaderCell>();

        for (BaseColumn column : columns) {
            UIComponent columnHeaderOrFooter = isHeader ? column.getSubHeader() : null;
            HeaderCell cell = new HeaderCell(column, columnHeaderOrFooter, cellTag, CellKind.COL_SUBHEADER);
            if (columnHeaderOrFooter != null)
                atLeastOneComponent = true;
            cell.setSpans(1, 0, 0);
            cells.add(cell);
        }
        if (!atLeastOneComponent)
            return null;
        return new HeaderRow(this, true, cells);
    }

    private List<HeaderRow> composeColumnHeaderRows(
            List<BaseColumn> columns,
            int startColIndex,
            int endColIndex,
            String cellTag) {
        int colCount = columns.size();
        List<BaseColumn>[] columnHierarchies = new ArrayList[colCount];
        int columnHierarchyLevels = composeColumnHierarchies(columns, columnHierarchies, isHeader, true);

        List<HeaderRow> rows = new ArrayList<HeaderRow>();
        for (int rowIndex = 0; rowIndex < columnHierarchyLevels; rowIndex++) {
            List<HeaderCell> rowCells = new ArrayList<HeaderCell>();
            boolean atLeastOneComponentInThisRow = false;
            for (int colIndex = startColIndex; colIndex < endColIndex; colIndex++) {
                HeaderCell cell = createCell(cellTag, columnHierarchies, columnHierarchyLevels, rowIndex, colIndex);
                if (cell == null)
                    continue;
                rowCells.add(cell);
                if (cell.getContent() != null)
                    atLeastOneComponentInThisRow = true;
                colIndex += cell.getColSpan() - 1;
            }
            HeaderRow row = new HeaderRow(this, atLeastOneComponentInThisRow, rowCells);
            row.setRowsForSpans(rows);
            if (isHeader)
                rows.add(row);
            else
                rows.add(0, row);
        }
        return rows;
    }

    private HeaderCell createCell(String cellTag,
                                  List[] columnHierarchies, int columnHierarchyLevels,
                                  int rowIndex, int colIndex) {
        List columnHierarchy = columnHierarchies[colIndex];
        int thisHierarchySize = columnHierarchy.size();

        boolean firstFooterRow = !isHeader && rowIndex == columnHierarchyLevels - 1;
        if (isHeader) {
            if (rowIndex >= thisHierarchySize)
                return null;
        } else {
            if (!firstFooterRow && rowIndex >= thisHierarchySize - 1)
                return null;
        }

        BaseColumn col = (BaseColumn) columnHierarchy.get(firstFooterRow ? thisHierarchySize - 1 : rowIndex);
        int colSpan = 1;
        for (int nextColIndex = colIndex + 1, colCount = columnHierarchies.length; nextColIndex < colCount; nextColIndex++) {
            List nextColumnHierarchy = columnHierarchies[nextColIndex];
            if (rowIndex >= nextColumnHierarchy.size())
                break;
            BaseColumn nextCol = (BaseColumn) nextColumnHierarchy.get(rowIndex);
            if (nextCol != col)
                break;
            colSpan++;
        }

        Object cellContent = getHeaderOrFooterCellContent(col, isHeader);
        HeaderCell cell = new HeaderCell(col, cellContent, cellTag, CellKind.COL_HEADER,
                isHeader, isHeader ? HeaderCell.SortingToggleMode.AUTODETECT : HeaderCell.SortingToggleMode.OFF);
        cell.setEscapeText(true);
        if (isHeader) {
            boolean lastInThisHierarchy = thisHierarchySize - 1 == rowIndex;
            cell.setSpans(colSpan, rowIndex, lastInThisHierarchy ? columnHierarchyLevels - 1 : rowIndex);
        } else {
            boolean verticallySpannedCell = rowIndex >= thisHierarchySize;
            cell.setSpans(colSpan, 0, verticallySpannedCell ? columnHierarchyLevels - thisHierarchySize : 0);
        }
        return cell;
    }

    public static Object getHeaderOrFooterCellContent(BaseColumn col, boolean isHeader) {
        DynamicCol dynamicCol = col instanceof DynamicCol ? (DynamicCol) col : null;
        Runnable restoreVariables = (dynamicCol != null) ? dynamicCol.enterComponentContext() : null;
        try {
            Object cellContent;
            if (isHeader) {
                cellContent = col.getHeader();
                if (cellContent == null)
                    cellContent = col.getHeaderValue();
            } else {
                cellContent = col.getFooter();
                if (cellContent == null)
                    cellContent = col.getFooterValue();
            }
            return cellContent;
        } finally {
            if (restoreVariables != null) restoreVariables.run();
        }
    }

    public boolean hasSubHeader() {
        return hasSubHeader;
    }

    @Override
    protected void fillInitParam(JSONObject initObject, TableStyles defaultStyles) throws JSONException {
        TableStructure tableStructure = getParent(TableStructure.class);
        TableStyles tableStyles = tableStructure.getTableStyles();
        FacesContext context = FacesContext.getCurrentInstance();
        UIComponent component = tableStructure.getComponent();
        String sectionClass = Styles.getCSSClass(context, component,
                isHeader ? tableStyles.getHeaderSectionStyle() : tableStyles.getFooterSectionStyle(),
                isHeader ? tableStyles.getHeaderSectionClass() : tableStyles.getFooterSectionClass());
        sectionClass = TableUtil.getClassWithDefaultStyleClass(
                tableStyles.getApplyDefaultStyle(),
                isHeader ? TableUtil.DEFAULT_HEADER_SECTION_CLASS : TableUtil.DEFAULT_FOOTER_SECTION_CLASS,
                sectionClass);

        if (!Rendering.isNullOrEmpty(sectionClass))
            initObject.put("className", sectionClass);
        if (tableStructure.getScrolling() != null)
            initObject.put("rowCount", allRows.size());
        if (commonHeaderRow != null)
            initObject.put("commonHeader", getCommonHeaderParam(tableStructure));
        if (hasSubHeader)
            initObject.put("subHeader", getSubHeaderParam(tableStructure));

        String headerClassName = Styles.getCSSClass(context, component,
                isHeader ? tableStyles.getHeaderRowStyle() : tableStyles.getFooterRowStyle(),
                isHeader ? tableStyles.getHeaderRowClass() : tableStyles.getFooterRowClass());
        if (!Rendering.isNullOrEmpty(headerClassName))
            initObject.put("headingsClassName", headerClassName);
    }

    private JSONObject getCommonHeaderParam(TableStructure tableStructure) throws JSONException {
        JSONObject result = new JSONObject();
        FacesContext context = FacesContext.getCurrentInstance();
        AbstractTable table = ((AbstractTable) tableStructure.getComponent());
        String commonHeaderClass = Styles.getCSSClass(context, tableStructure.getComponent(),
                isHeader ? table.getCommonHeaderRowStyle() : table.getCommonFooterRowStyle(),
                isHeader ? table.getCommonHeaderRowClass() : table.getCommonFooterRowClass());
        if (!Rendering.isNullOrEmpty(commonHeaderClass))
            result.put("className", commonHeaderClass);
        return result;
    }

    private JSONObject getSubHeaderParam(TableStructure tableStructure) throws JSONException {
        JSONObject result = new JSONObject();
        FacesContext context = FacesContext.getCurrentInstance();
        AbstractTable table = ((AbstractTable) tableStructure.getComponent());
        String className = Styles.getCSSClass(context, table, getSubHeaderRowStyle(table),
                StyleGroup.regularStyleGroup(), getSubHeaderRowClass(table), DEFAULT_SUBHEADER_ROW_CELLS_CLASS);
        if (!Rendering.isNullOrEmpty(className))
            result.put("className", className);

        return result;
    }

    private String getSubHeaderRowClass(TableStyles tableStyles) {
        if (!(tableStyles instanceof AbstractTable))
            return null;
        AbstractTable table = ((AbstractTable) tableStyles);
        return table.getSubHeaderRowClass();
    }

    private String getSubHeaderRowStyle(TableStyles tableStyles) {
        if (!(tableStyles instanceof AbstractTable))
            return null;
        AbstractTable table = ((AbstractTable) tableStyles);
        return table.getSubHeaderRowStyle();
    }

    protected String getSectionName() {
        return isHeader ? "thead" : "tfoot";
    }

    protected void renderRows(FacesContext facesContext, HeaderCell.AdditionalContentWriter additionalContentWriter) throws IOException {
        for (int i = 0, count = allRows.size(); i < count; i++) {
            HeaderRow row = allRows.get(i);
            row.render(facesContext, i == count - 1 ? additionalContentWriter : null);
        }
    }

    @Override
    public boolean isContentSpecified() {
        if (allRows.size() == 0)
            return false;
        for (AbstractRow row : allRows)
            if (row.isAtLeastOneComponentInThisRow())
                return true;
        return false;
    }

    public int getSubHeaderRowIndex() {
        if (!hasSubHeader())
            return -1;
        if (!isHeader)
            return 0;
        int subHeaderRowIndex = lastVisibleColHeadersRow + 1;
        if (commonHeaderRow != null)
            subHeaderRowIndex++;
        return subHeaderRowIndex;
    }

    public CellCoordinates findCell(BaseColumn column, CellKind cellKind) {
        if (allRows.size() == 0)
            return null;
        TableStructure tableStructure = getParent(TableStructure.class);
        if (tableStructure.getScrolling() == null) {
            boolean skipFirstRow = isHeader ? commonHeaderRow != null : hasSubHeader;
            List<HeaderRow> columnHeaderRows = allRows.subList(skipFirstRow ? 1 : 0, allRows.size());
            CellCoordinates cellCoordinates = findCell(column, columnHeaderRows, cellKind);
            if (cellCoordinates != null && isHeader && commonHeaderRow != null)
                cellCoordinates.setRowIndex(cellCoordinates.getRowIndex() + 1);
            return cellCoordinates;
        } else {
            int rowIndex = isHeader
                    ? (commonHeaderRow != null ? 1 : 0)
                    : allRows.size() - 1 - (commonHeaderRow != null ? 1 : 0);
            HeaderRow row = rowIndex >= 0 && rowIndex < allRows.size() ? allRows.get(rowIndex) : null;
            if (row == null) return null;
           
            List<HeaderCell> cells = row.getCells();
            for (int i = 0, count = cells.size(); i < count; i++) {
                HeaderCell cell = cells.get(i);
                TableScrollingArea scrollingArea = (TableScrollingArea) cell.getContent();
                List<HeaderRow> rows = (List<HeaderRow>) scrollingArea.getRows();
                CellCoordinates coords = findCell(column, rows, cellKind);
                if (coords != null) {
                    coords.setScrollAreaIndex(i);
                    return coords;
                }
            }
            return null;
        }
    }

    private CellCoordinates findCell(
            BaseColumn column,
            List<HeaderRow> columnHeaderRows,
            CellKind cellKind) {
        int rowIndex = getIeDocModeAdditionalSupportNeeded() ? 1 : 0;
        for (HeaderRow row : columnHeaderRows) {
            if (!row.isAtLeastOneComponentInThisRow())
                continue;
            List cells = row.getCells();
            for (int cellIndex = 0; cellIndex < cells.size(); cellIndex++) {
                HeaderCell cell = (HeaderCell) cells.get(cellIndex);
                if (cell.getColumn() == column && cell.getCellKind() == cellKind) {
                    return new CellCoordinates(rowIndex, cellIndex);
                }
            }
            rowIndex++;
        }

        return null;
    }

}
TOP

Related Classes of org.openfaces.renderkit.table.TableHeaderOrFooter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.