/* * #%L * Lapis JSF Exporter - PrimeFaces export sources * %% * Copyright (C) 2013 - 2015 Lapis Software Associates * %% * 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. * #L% */ package com.lapis.jsfexporter.primefaces.datatable; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashSet; import java.util.List; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import org.primefaces.component.api.DynamicColumn; import org.primefaces.component.api.UIColumn; import org.primefaces.component.columngroup.ColumnGroup; import org.primefaces.component.datatable.DataTable; import org.primefaces.component.row.Row; import com.lapis.jsfexporter.api.FacetType; import com.lapis.jsfexporter.api.IExportCell; import com.lapis.jsfexporter.api.IExportType; import com.lapis.jsfexporter.impl.ExportCellImpl; import com.lapis.jsfexporter.impl.ExportRowImpl; import com.lapis.jsfexporter.primefaces.util.PrimeFacesUtil; import com.lapis.jsfexporter.spi.IExportSource; import com.lapis.jsfexporter.util.ExportUtil; public class DataTableExportSource implements IExportSource<DataTable, DataTableExportOptions> { @Override public Class<DataTable> getSourceType() { return DataTable.class; } @Override public DataTableExportOptions getDefaultConfigOptions() { return new DataTableExportOptions(); } @Override public int getColumnCount(DataTable source, DataTableExportOptions configOptions) { return getColumnsForExport(source).size(); } @Override public void exportData(DataTable source, DataTableExportOptions configOptions, IExportType<?, ?, ?> exporter, FacesContext context) throws Exception { List<UIColumn> columns = getColumnsForExport(source); List<List<String>> columnNames = exportFacet(FacetType.HEADER, source, columns, exporter, context); if (configOptions.getRange() == DataTableExportRange.ALL) { if (source.isLazy()) { int first = source.getFirst(); int rowCount = source.getRowCount(); int rowsPerPage = source.getRows(); int passes = rowCount / rowsPerPage; // integer division rounds towards zero int finalPass = rowCount % rowsPerPage; for (int i = 0; i < passes; i++) { source.setFirst(i * rowsPerPage); source.loadLazyData(); exportRowCells(source, columns, columnNames, i * rowsPerPage, (i + 1) * rowsPerPage, exporter, context); } if (finalPass > 0) { source.setFirst(passes * rowsPerPage); source.loadLazyData(); exportRowCells(source, columns, columnNames, passes * rowsPerPage, (passes * rowsPerPage) + finalPass, exporter, context); } source.setFirst(first); source.loadLazyData(); } else { exportRowCells(source, columns, columnNames, 0, source.getRowCount(), exporter, context); } } else { // PAGE_ONLY exportRowCells(source, columns, columnNames, source.getFirst(), source.getFirst() + source.getRows(), exporter, context); } exportFacet(FacetType.FOOTER, source, columns, exporter, context); } private List<UIColumn> getColumnsForExport(DataTable source) { List<UIColumn> columns = new ArrayList<UIColumn>(); for (UIColumn kid : source.getColumns()) { if (kid.isRendered() && kid.isExportable()) { columns.add(kid); } } return columns; } private List<List<String>> exportFacet(FacetType facetType, DataTable source, List<UIColumn> columns, IExportType<?, ?, ?> exporter, FacesContext context) { List<List<String>> columnNames = new ArrayList<List<String>>(); List<IExportCell> facetCells = new ArrayList<IExportCell>(); ColumnGroup columnGroup = source.getColumnGroup(facetType.getFacetName()); if (columnGroup == null) { boolean hasFacet = false; for (UIColumn column : columns) { handleDynamicColumn(column); String facetText = PrimeFacesUtil.getColumnFacetText(column, facetType, context); if (facetText != null) { hasFacet = true; } columnNames.add(Arrays.asList(facetText)); } if (hasFacet) { for (List<String> columnName : columnNames) { facetCells.add(new ExportCellImpl(Arrays.asList(facetType.getFacetName()), columnName.get(0), 1, 1)); } exporter.exportRow(new ExportRowImpl(Arrays.asList(facetType.getFacetName()), null, facetType, facetCells)); } } else if (columnGroup.getChildCount() > 0) { int rowCount = columnGroup.getChildCount(); int colCount = 0; for (int i = 0; i < columnGroup.getChildren().get(0).getChildCount(); i++) { colCount += ((UIColumn) columnGroup.getChildren().get(0).getChildren().get(i)).getColspan(); } for (int i = 0; i < colCount; i++) { List<String> columnName = new ArrayList<String>(); for (int j = 0; j < rowCount; j++) { columnName.add(null); } columnNames.add(columnName); } for (int rowIndex = 0; rowIndex < columnGroup.getChildCount(); rowIndex++) { Row row = (Row) columnGroup.getChildren().get(rowIndex); int columnIndex = 0; for (UIComponent rowChild : row.getChildren()) { UIColumn rowColumn = (UIColumn) rowChild; String facetText = PrimeFacesUtil.getColumnFacetText(rowColumn, facetType, context); while (columnNames.get(columnIndex).get(rowIndex) != null) { columnIndex++; } for (int i = 0; i < rowColumn.getColspan(); i++) { for (int j = 0; j < rowColumn.getRowspan(); j++) { columnNames.get(columnIndex).set(rowIndex + j, facetText); } columnIndex++; } facetCells.add(new ExportCellImpl(Arrays.asList(facetType.getFacetName()), facetText, rowColumn.getColspan(), rowColumn.getRowspan())); } exporter.exportRow(new ExportRowImpl(Arrays.asList(facetType.getFacetName()), null, facetType, facetCells)); facetCells.clear(); } } for (int i = 0; i < columnNames.size(); i++) { columnNames.set(i, new ArrayList<String>(new LinkedHashSet<String>(columnNames.get(i)))); } return columnNames; } private void exportRowCells(DataTable source, List<UIColumn> columns, List<List<String>> columnNames, int startingRow, int endingRow, IExportType<?, ?, ?> exporter, FacesContext context) { List<String> rowName = Arrays.asList(source.getVar()); List<IExportCell> cells = new ArrayList<IExportCell>(); int columnCount = columns.size(); for (int i = startingRow; i < endingRow; i++) { source.setRowIndex(i); for (int j = 0; j < columnCount; j++) { cells.add(new ExportCellImpl(columnNames.get(j), ExportUtil.transformComponentsToString(context, handleDynamicColumn(columns.get(j)).getChildren()), 1, 1)); } exporter.exportRow(new ExportRowImpl(rowName, null, null, cells)); cells.clear(); } } private UIColumn handleDynamicColumn(UIColumn column) { if (column instanceof DynamicColumn) { ((DynamicColumn) column).applyStatelessModel(); } return column; } }