Package org.pentaho.reporting.engine.classic.core.layout.output.crosstab

Source Code of org.pentaho.reporting.engine.classic.core.layout.output.crosstab.CrosstabRowOutputHandler

/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program 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.
* See the GNU Lesser General Public License for more details.
*
* Copyright (c) 2002-2013 Pentaho Corporation..  All rights reserved.
*/

package org.pentaho.reporting.engine.classic.core.layout.output.crosstab;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.reporting.engine.classic.core.CrosstabCell;
import org.pentaho.reporting.engine.classic.core.CrosstabCellBody;
import org.pentaho.reporting.engine.classic.core.CrosstabColumnGroup;
import org.pentaho.reporting.engine.classic.core.CrosstabColumnGroupBody;
import org.pentaho.reporting.engine.classic.core.CrosstabRowGroup;
import org.pentaho.reporting.engine.classic.core.CrosstabRowGroupBody;
import org.pentaho.reporting.engine.classic.core.Group;
import org.pentaho.reporting.engine.classic.core.GroupBody;
import org.pentaho.reporting.engine.classic.core.ReportProcessingException;
import org.pentaho.reporting.engine.classic.core.event.ReportEvent;
import org.pentaho.reporting.engine.classic.core.layout.Renderer;
import org.pentaho.reporting.engine.classic.core.layout.build.LayoutModelBuilder;
import org.pentaho.reporting.engine.classic.core.layout.model.RenderBox;
import org.pentaho.reporting.engine.classic.core.layout.model.RenderNode;
import org.pentaho.reporting.engine.classic.core.layout.model.table.TableCellRenderBox;
import org.pentaho.reporting.engine.classic.core.layout.model.table.TableSectionRenderBox;
import org.pentaho.reporting.engine.classic.core.layout.output.DefaultOutputFunction;
import org.pentaho.reporting.engine.classic.core.layout.output.GroupOutputHandler;
import org.pentaho.reporting.engine.classic.core.style.BandStyleKeys;
import org.pentaho.reporting.engine.classic.core.util.InstanceID;

public class CrosstabRowOutputHandler implements GroupOutputHandler
{
  private static final Log logger = LogFactory.getLog (CrosstabRowOutputHandler.class);

  public CrosstabRowOutputHandler()
  {
  }

  public void groupStarted(final DefaultOutputFunction outputFunction,
                           final ReportEvent event) throws ReportProcessingException
  {
    final RenderedCrosstabLayout crosstabLayout = outputFunction.getCurrentRenderedCrosstabLayout();
    final LayoutModelBuilder layoutModelBuilder = outputFunction.getRenderer().getNormalFlowLayoutModelBuilder();
    final int gidx = event.getState().getCurrentGroupIndex();
    final CrosstabRowGroup group = (CrosstabRowGroup) event.getReport().getGroup(gidx);

    if (crosstabLayout.isCrosstabTableOpen() == false)
    {
      buildHeaderPlaceholder(crosstabLayout, layoutModelBuilder);
      crosstabLayout.setFirstRowGroupIndex(gidx);
      crosstabLayout.setCrosstabTableOpen(true);
    }

    if (crosstabLayout.isCrosstabHeaderOpen())
    {
      layoutModelBuilder.startSubFlow(crosstabLayout.getRowTitleHeaderId());
      CrosstabOutputHelper.createAutomaticCell(layoutModelBuilder);
      outputFunction.getRenderer().add(group.getTitleHeader(), outputFunction.getRuntime());
      layoutModelBuilder.finishBox();
      layoutModelBuilder.suspendSubFlow();
    }

    if (crosstabLayout.isCrosstabRowOpen() == false)
    {
      // start a new row if needed ..
      layoutModelBuilder.startBox(CrosstabOutputHelper.createTableRow());
      crosstabLayout.setCrosstabRowOpen(true);

      // flag not empty is needed to connect the new node with the rest of the layout model.
      layoutModelBuilder.legacyFlagNotEmpty();
      final TableSectionRenderBox rowRenderNode = CrosstabOutputHelper.findTableSection(layoutModelBuilder.dangerousRawAccess());

      for (int i = crosstabLayout.getFirstRowGroupIndex(), count = 0; i < gidx; i += 1, count += 1)
      {
        final InstanceID rowHeader = crosstabLayout.getRowHeader(i - crosstabLayout.getFirstRowGroupIndex());
        final RenderNode cell = CrosstabOutputHelper.findNode(rowRenderNode, rowHeader);
        if (cell instanceof TableCellRenderBox)
        {
          final TableCellRenderBox cellBox = (TableCellRenderBox) cell;
          cellBox.update(cellBox.getRowSpan() + 1, cellBox.getColSpan());
        }
        else
        {
          throw new IllegalStateException("Unable to find previously defined row header. Aborting report processing.");
        }
      }
    }

    final int firstRowGroupIndex = crosstabLayout.getFirstRowGroupIndex();
    if (gidx == firstRowGroupIndex)
    {
      RenderNode renderNode = layoutModelBuilder.dangerousRawAccess();
      RenderBox parentNode = (RenderBox) CrosstabOutputHelper.findParentNode(renderNode, crosstabLayout.getCrosstabId());
      parentNode.setPreventPagination(true);
    }

    CrosstabOutputHelper.createAutomaticCell(layoutModelBuilder, 1, 1, group.getHeader());
    crosstabLayout.setRowHeader(gidx - crosstabLayout.getFirstRowGroupIndex(), layoutModelBuilder.dangerousRawAccess().getInstanceId());
    outputFunction.getRenderer().add(group.getHeader(), outputFunction.getRuntime());
    layoutModelBuilder.finishBox();
  }


  public void groupFinished(final DefaultOutputFunction outputFunction,
                            final ReportEvent event) throws ReportProcessingException
  {
    CrosstabOutputHelper.printCrosstabSummary(outputFunction, event);

    final RenderedCrosstabLayout crosstabLayout = outputFunction.getCurrentRenderedCrosstabLayout();
    final LayoutModelBuilder layoutModelBuilder = outputFunction.getRenderer().getNormalFlowLayoutModelBuilder();

    if (crosstabLayout.isCrosstabRowOpen())
    {
      layoutModelBuilder.finishBox(); // Table-Row
      crosstabLayout.setCrosstabRowOpen(false);
    }

    if (crosstabLayout.isCrosstabHeaderOpen())
    {
      // close all header rows
      final InstanceID[] columnHeaders = crosstabLayout.getColumnHeaderSubFlows();
      for (int i = 0; i < columnHeaders.length; i++)
      {
        final InstanceID columnHeader = columnHeaders[i];
        layoutModelBuilder.startSubFlow(columnHeader);
        layoutModelBuilder.endSubFlow();
      }
      crosstabLayout.setCrosstabHeaderOpen(false);
    }

    final int gidx = event.getState().getCurrentGroupIndex();
    final int firstRowGroupIndex = crosstabLayout.getFirstRowGroupIndex();
    if (gidx == firstRowGroupIndex)
    {
      RenderNode renderNode = layoutModelBuilder.dangerousRawAccess();
      RenderBox parentNode = (RenderBox) CrosstabOutputHelper.findParentNode(renderNode, crosstabLayout.getCrosstabId());
      parentNode.setPreventPagination(false);
    }
  }

  public void groupBodyFinished(final DefaultOutputFunction outputFunction,
                                final ReportEvent event) throws ReportProcessingException
  {

  }

  private void buildHeaderPlaceholder(final RenderedCrosstabLayout crosstabLayout,
                                      final LayoutModelBuilder layoutModelBuilder)
  {
    crosstabLayout.setCrosstabId
        (layoutModelBuilder.startBox(CrosstabOutputHelper.createTable(crosstabLayout.getTableLayout())));

    layoutModelBuilder.startBox(CrosstabOutputHelper.createTableBand(BandStyleKeys.LAYOUT_TABLE_HEADER));

    // create column group placeholder rows. We subsequently add content as sub-flows into these groups.
    int columnGroupCount = crosstabLayout.getColumnGroups();
    if (crosstabLayout.isGenerateColumnTitleHeaders())
    {
      columnGroupCount += crosstabLayout.getColumnGroups();
    }
    if (crosstabLayout.isGenerateMeasureHeaders())
    {
      columnGroupCount += 1;
    }
    final InstanceID[] columnHeaders = new InstanceID[Math.max(1, columnGroupCount)];
    for (int i = 0; i < columnHeaders.length; i += 1)
    {
      columnHeaders[i] = layoutModelBuilder.createSubflowPlaceholder(CrosstabOutputHelper.createTableRow());
    }

    if (columnHeaders.length > 1)
    {
      // Adds a empty cell that consumes the area above the row-header
      layoutModelBuilder.startSubFlow(columnHeaders[0]);
      CrosstabOutputHelper.createAutomaticCell(layoutModelBuilder, crosstabLayout.getRowGroups(), columnHeaders.length - 1);
      layoutModelBuilder.legacyFlagNotEmpty();
      layoutModelBuilder.finishBox();
      layoutModelBuilder.suspendSubFlow();
    }

    layoutModelBuilder.finishBox(); // BandStyleKeys.LAYOUT_TABLE_HEADER

    layoutModelBuilder.startBox(CrosstabOutputHelper.createTableBand(BandStyleKeys.LAYOUT_TABLE_BODY));


    crosstabLayout.setCrosstabHeaderOpen(true);
    crosstabLayout.setColumnHeaderRowIds(columnHeaders);
  }

  public void itemsStarted(final DefaultOutputFunction outputFunction,
                           final ReportEvent event) throws ReportProcessingException
  {
    throw new ReportProcessingException("A crosstab-row cannot contain a detail band. Never.");
  }

  public void itemsAdvanced(final DefaultOutputFunction outputFunction,
                            final ReportEvent event) throws ReportProcessingException
  {
    throw new ReportProcessingException("A crosstab-row cannot contain a detail band. Never.");
  }

  public void itemsFinished(final DefaultOutputFunction outputFunction,
                            final ReportEvent event) throws ReportProcessingException
  {
    throw new ReportProcessingException("A crosstab-row cannot contain a detail band. Never.");
  }

  public void summaryRowStart(final DefaultOutputFunction outputFunction,
                              final ReportEvent event) throws ReportProcessingException
  {
    final RenderedCrosstabLayout crosstabLayout = outputFunction.getCurrentRenderedCrosstabLayout();
    final LayoutModelBuilder layoutModelBuilder = outputFunction.getRenderer().getNormalFlowLayoutModelBuilder();

    if (crosstabLayout.isCrosstabRowOpen())
    {
      throw new IllegalStateException("Event Order Error: A summary row cannot be printed while a row is still open.");
    }

    final int gidx = event.getState().getCurrentGroupIndex() + 1;
    final CrosstabRowGroup group = (CrosstabRowGroup) event.getReport().getGroup(gidx);

    if (group.isPrintSummary() == false)
    {
      crosstabLayout.startSummaryRowProcessing(false, gidx, null);
      return;
    }
   
    if (group.getField() == null)
    {
      crosstabLayout.startSummaryRowProcessing(false, gidx, null);
      return;
    }

    final CrosstabCellBody dataBody = event.getReport().getCrosstabCellBody();
    final CrosstabCell element = dataBody.findElement(group.getField(), null);
    if (element == null)
    {
      crosstabLayout.startSummaryRowProcessing(false, gidx, null);
      return;
    }

    if (crosstabLayout.isCrosstabRowOpen() == false)
    {
      // start a new row if needed ..
      layoutModelBuilder.startBox(CrosstabOutputHelper.createTableRow());
      crosstabLayout.setCrosstabRowOpen(true);

      // flag not empty is needed to connect the new node with the rest of the layout model.
      layoutModelBuilder.legacyFlagNotEmpty();
      final TableSectionRenderBox rowRenderNode = CrosstabOutputHelper.findTableSection(layoutModelBuilder.dangerousRawAccess());
      for (int i = crosstabLayout.getFirstRowGroupIndex(), count = 0; i < gidx; i += 1, count += 1)
      {
        final InstanceID rowHeader = crosstabLayout.getRowHeader(i - crosstabLayout.getFirstRowGroupIndex());
        final RenderNode cell = CrosstabOutputHelper.findNode(rowRenderNode, rowHeader);
        if (cell instanceof TableCellRenderBox)
        {
          final TableCellRenderBox cellBox = (TableCellRenderBox) cell;
          cellBox.update(cellBox.getRowSpan() + 1, cellBox.getColSpan());
        }
        else
        {
          throw new IllegalStateException("Unable to find previously defined row header. Aborting report processing.");
        }
      }
    }

    // An outer row-group's summary cell spans across all inner row-group header-columns up to the start
    // of the data area.
    final int colSpan = crosstabLayout.getFirstColGroupIndex() - gidx;
    CrosstabOutputHelper.createAutomaticCell(layoutModelBuilder, colSpan, 1, group.getSummaryHeader());
    crosstabLayout.setRowHeader(gidx - crosstabLayout.getFirstRowGroupIndex(), layoutModelBuilder.dangerousRawAccess().getInstanceId());
    outputFunction.getRenderer().add(group.getSummaryHeader(), outputFunction.getRuntime());
    layoutModelBuilder.finishBox();

    crosstabLayout.startSummaryRowProcessing(true, gidx, group.getField());
    crosstabLayout.setDetailsRendered(false);
    crosstabLayout.setProcessingCrosstabHeader(false);
  }

  public void summaryRowEnd(final DefaultOutputFunction outputFunction,
                            final ReportEvent event) throws ReportProcessingException
  {
    final RenderedCrosstabLayout crosstabLayout = outputFunction.getCurrentRenderedCrosstabLayout();
    if (crosstabLayout.isSummaryRowPrintable() == false)
    {
      return;
    }

    final LayoutModelBuilder layoutModelBuilder = outputFunction.getRenderer().getNormalFlowLayoutModelBuilder();

    if (crosstabLayout.isCrosstabRowOpen())
    {
      printSummaryCell(outputFunction, event);

      layoutModelBuilder.finishBox(); // Table-Row
      crosstabLayout.setCrosstabRowOpen(false);
    }
  }

  public void summaryRow(final DefaultOutputFunction outputFunction,
                         final ReportEvent event) throws ReportProcessingException
  {
    final RenderedCrosstabLayout crosstabLayout = outputFunction.getCurrentRenderedCrosstabLayout();
    if (crosstabLayout.isSummaryRowPrintable() == false)
    {
      return;
    }

    printSummaryCell(outputFunction, event);
  }

  private void printSummaryCell(final DefaultOutputFunction outputFunction,
                                final ReportEvent event) throws ReportProcessingException
  {
    final RenderedCrosstabLayout crosstabLayout = outputFunction.getCurrentRenderedCrosstabLayout();

    final int gidx = event.getState().getCurrentGroupIndex();
    final Group group = event.getReport().getGroup(gidx);
    final String columnField;
    final GroupBody groupBody = group.getBody();
    if (groupBody instanceof CrosstabColumnGroupBody)
    {
      final CrosstabColumnGroupBody columnGroupBody = (CrosstabColumnGroupBody) groupBody;
      final CrosstabColumnGroup next = columnGroupBody.getGroup();
      if (next.isPrintSummary() == false)
      {
        return;
      }
      columnField = next.getField();
    }
    else if (groupBody instanceof CrosstabRowGroupBody)
    {
      // the final sum of the row. The column field will be the first column group
      final CrosstabColumnGroup colGroup = (CrosstabColumnGroup)
          event.getReport().getGroup(crosstabLayout.getFirstColGroupIndex());
      if (colGroup.isPrintSummary() == false)
      {
        return;
      }
      columnField = colGroup.getField();
    }
    else
    {
      // a detail level summary row cell.
      columnField = null;
    }

    final LayoutModelBuilder layoutModelBuilder = outputFunction.getRenderer().getNormalFlowLayoutModelBuilder();
    final CrosstabCellBody dataBody = event.getReport().getCrosstabCellBody();
    final CrosstabCell element = dataBody.findElement(crosstabLayout.getSummaryRowField(), columnField);

    if (element != null)
    {
      CrosstabOutputHelper.createAutomaticCell(layoutModelBuilder);
      layoutModelBuilder.legacyFlagNotEmpty();
      outputFunction.getRenderer().startSection(Renderer.SectionType.NORMALFLOW);
      outputFunction.getRenderer().add(element, outputFunction.getRuntime());
      outputFunction.addSubReportMarkers(outputFunction.getRenderer().endSection());
      layoutModelBuilder.finishBox();
    }
    else
    {
      CrosstabOutputHelper.createAutomaticCell(layoutModelBuilder);
      layoutModelBuilder.legacyFlagNotEmpty();
      logger.debug(String.format("Unable to find summary cell: %s - %s", // NON-NLS
          crosstabLayout.getSummaryRowField(), columnField));
      layoutModelBuilder.finishBox();
    }

  }
}
TOP

Related Classes of org.pentaho.reporting.engine.classic.core.layout.output.crosstab.CrosstabRowOutputHandler

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.