Package org.pentaho.reporting.engine.classic.core.states.datarow

Source Code of org.pentaho.reporting.engine.classic.core.states.datarow.GlobalMasterRow

/*
* 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) 2001 - 2009 Object Refinery Ltd, Pentaho Corporation and Contributors..  All rights reserved.
*/

package org.pentaho.reporting.engine.classic.core.states.datarow;

import org.pentaho.reporting.engine.classic.core.DataFactory;
import org.pentaho.reporting.engine.classic.core.DataRow;
import org.pentaho.reporting.engine.classic.core.ParameterDataRow;
import org.pentaho.reporting.engine.classic.core.ReportEnvironmentDataRow;
import org.pentaho.reporting.engine.classic.core.ResourceBundleFactory;
import org.pentaho.reporting.engine.classic.core.event.ReportEvent;
import org.pentaho.reporting.engine.classic.core.function.ProcessingContext;
import org.pentaho.reporting.engine.classic.core.layout.output.OutputProcessorMetaData;
import org.pentaho.reporting.engine.classic.core.parameters.ParameterDefinitionEntry;
import org.pentaho.reporting.engine.classic.core.states.CascadingDataFactory;
import org.pentaho.reporting.engine.classic.core.states.EmptyDataFactory;
import org.pentaho.reporting.engine.classic.core.states.ReportState;
import org.pentaho.reporting.engine.classic.core.states.crosstab.CrosstabSpecification;
import org.pentaho.reporting.engine.classic.core.wizard.DataSchema;
import org.pentaho.reporting.engine.classic.core.wizard.DataSchemaDefinition;
import org.pentaho.reporting.engine.classic.core.wizard.DefaultDataAttributeContext;

/**
* Creation-Date: Dec 13, 2006, 2:52:23 PM
*
* @author Thomas Morgner
*/
public final class GlobalMasterRow implements MasterDataRow
{
  private ReportEnvironmentDataRow environmentDataRow;
  private DataFactory dataFactory;
  private ReportDataRow reportDataRow;
  private ExpressionDataRow expressionDataRow;
  private ParameterDataRow parameterDataRow;
  private MasterDataRow parentRow;
  private FastGlobalView globalView;
  private ImportedVariablesDataRow importedDataRow;
  private DataSchemaDefinition schemaDefinition;
  private ProcessingDataSchemaCompiler schemaCompiler;
  private DataSchema dataSchema;
  private PaddingDataRow paddingDataRow;
  private int prePaddingCount;
  private ResourceBundleFactory resourceBundleFactory;
  private OutputProcessorMetaData outputProcessorMetaData;
  private ParameterDefinitionEntry[] parameterDefinitionEntries;

  private GlobalMasterRow()
  {
  }

  /**
   * Creates a new master-row. This is called only once when the report processing starts for the very first time.
   *
   * @param reportContext
   * @param schemaDefinition
   * @param parameterDataRow
   * @return
   */
  public static GlobalMasterRow createReportRow(final ProcessingContext reportContext,
                                                final DataSchemaDefinition schemaDefinition,
                                                final ParameterDataRow parameterDataRow,
                                                final ParameterDefinitionEntry[] parameterDefinitionEntries,
                                                final boolean includeStucturalProcessing)
  {
    if (reportContext == null)
    {
      throw new NullPointerException();
    }
    if (schemaDefinition == null)
    {
      throw new NullPointerException();
    }
    if (parameterDataRow == null)
    {
      throw new NullPointerException();
    }

    final GlobalMasterRow gmr = new GlobalMasterRow();
    gmr.globalView = new FastGlobalView();
    gmr.expressionDataRow = new ExpressionDataRow(gmr, reportContext, includeStucturalProcessing);
    gmr.schemaDefinition = schemaDefinition;
    gmr.dataFactory = new EmptyDataFactory();
    gmr.resourceBundleFactory = reportContext.getResourceBundleFactory();
    gmr.outputProcessorMetaData = reportContext.getOutputProcessorMetaData();
    final DefaultDataAttributeContext dac = new DefaultDataAttributeContext
        (gmr.outputProcessorMetaData, gmr.getResourceBundleFactory().getLocale());
    gmr.schemaCompiler =
        new ProcessingDataSchemaCompiler(schemaDefinition, dac, reportContext.getResourceManager(), null);
    gmr.dataSchema = null;
    gmr.parameterDefinitionEntries = parameterDefinitionEntries;
    gmr.setEnvironmentDataRow(new ReportEnvironmentDataRow(reportContext.getEnvironment()));
    gmr.setParameterDataRow(parameterDataRow);
    return gmr;
  }

  public MasterDataRow deriveSubDataRow(final ProcessingContext reportContext,
                                        final DataFactory reportFactory,
                                        final ParameterDataRow parameterDataRow,
                                        final ParameterDefinitionEntry[] parameterDefinitionEntries,
                                        final ResourceBundleFactory resourceBundleFactory)
  {
    if (reportContext == null)
    {
      throw new NullPointerException();
    }
    if (reportFactory == null)
    {
      throw new NullPointerException();
    }
    if (resourceBundleFactory == null)
    {
      throw new NullPointerException();
    }
    if (parameterDataRow == null)
    {
      throw new NullPointerException();
    }
    final GlobalMasterRow gmr = new GlobalMasterRow();
    gmr.outputProcessorMetaData = outputProcessorMetaData;
    gmr.schemaDefinition = schemaDefinition;
    gmr.schemaCompiler = schemaCompiler;
    gmr.globalView = new FastGlobalView();
    gmr.expressionDataRow = new ExpressionDataRow
        (gmr, reportContext, expressionDataRow.isIncludeStructuralProcessing());
    gmr.parentRow = this;
    gmr.dataSchema = null;
    gmr.resourceBundleFactory = resourceBundleFactory;
    gmr.parameterDefinitionEntries = parameterDefinitionEntries;

    final CascadingDataFactory dataFactory = new CascadingDataFactory();
    dataFactory.add(reportFactory);
    dataFactory.add(this.dataFactory);
    gmr.dataFactory = dataFactory;
    gmr.setParameterDataRow(parameterDataRow);
    gmr.setEnvironmentDataRow(environmentDataRow);
    return gmr;
  }

  public MasterDataRow deriveWithQueryData(final ReportDataRow tableData)
  {
    if (tableData == null)
    {
      throw new NullPointerException();
    }

    final GlobalMasterRow derived = (GlobalMasterRow) derive();
    derived.setReportDataRow(tableData);
    return derived;
  }

  public MasterDataRow deriveWithReturnFromQuery()
  {
    final GlobalMasterRow derived = (GlobalMasterRow) derive();
    derived.setReportDataRow(null);
    derived.setParameterDataRow(null);
    return derived;
  }

  public ParameterDefinitionEntry[] getParameterDefinitionEntries()
  {
    if (parameterDefinitionEntries == null)
    {
      return null;
    }
    return parameterDefinitionEntries.clone();
  }

  public DataFactory getDataFactory()
  {
    return dataFactory;
  }

  public DataSchema getDataSchema()
  {
    if (dataSchema == null)
    {
      dataSchema = schemaCompiler.compile(this, environmentDataRow.getEnvironment());
    }
    return dataSchema;
  }

  public ReportDataRow getReportDataRow()
  {
    return reportDataRow;
  }

  public void setReportDataRow(final ReportDataRow reportDataRow)
  {
    if (this.reportDataRow != null)
    {
      final int dataColCount = this.reportDataRow.getColumnCount();
      for (int i = dataColCount - 1; i >= 0; i--)
      {
        final String columnName = this.reportDataRow.getColumnName(i);
        if (columnName != null)
        {
          globalView.removeColumn(columnName);
        }
      }
    }

    this.reportDataRow = reportDataRow;

    if (reportDataRow != null)
    {
      final boolean readable = reportDataRow.isReadable();
      final int dataColCount = reportDataRow.getColumnCount();
      for (int i = 0; i < dataColCount; i++)
      {
        final String columnName = reportDataRow.getColumnName(i);
        if (columnName != null)
        {
          if (readable)
          {
            final Object columnValue = reportDataRow.get(i);
            globalView.putField(columnName, columnValue, false);
          }
          else
          {
            globalView.putField(columnName, null, false);
          }
        }
      }
    }

    this.dataSchema = null;
  }

  public ExpressionDataRow getExpressionDataRow()
  {
    return expressionDataRow;
  }

  public ReportEnvironmentDataRow getEnvironmentDataRow()
  {
    return environmentDataRow;
  }

  public void setEnvironmentDataRow(final ReportEnvironmentDataRow environmentDataRow)
  {
    if (this.environmentDataRow != null)
    {
      final String[] columnNames = this.environmentDataRow.getColumnNames();
      for (int i = 0; i < columnNames.length; i++)
      {
        final String columnName = columnNames[i];
        if (columnName != null)
        {
          globalView.removeColumn(columnName);
        }
      }
    }

    this.environmentDataRow = environmentDataRow;

    if (environmentDataRow != null)
    {
      final String[] columnNames = environmentDataRow.getColumnNames();
      for (int i = 0; i < columnNames.length; i++)
      {
        final String columnName = columnNames[i];
        if (columnName != null)
        {
          final Object columnValue = environmentDataRow.get(columnName);
          globalView.putField(columnName, columnValue, false);
        }
      }
    }

    this.dataSchema = null;
  }

  public ParameterDataRow getParameterDataRow()
  {
    return parameterDataRow;
  }

  public void setParameterDataRow(final ParameterDataRow parameterDataRow)
  {
    if (this.parameterDataRow != null)
    {
      final String[] columnNames = this.parameterDataRow.getColumnNames();
      for (int i = 0; i < columnNames.length; i++)
      {
        final String columnName = columnNames[i];
        if (columnName != null)
        {
          globalView.removeColumn(columnName);
        }
      }
    }

    this.parameterDataRow = parameterDataRow;

    if (parameterDataRow != null)
    {
      final String[] columnNames = parameterDataRow.getColumnNames();
      for (int i = 0; i < columnNames.length; i++)
      {
        final String columnName = columnNames[i];
        if (columnName != null)
        {
          final Object columnValue = parameterDataRow.get(columnName);
          globalView.putField(columnName, columnValue, false);
        }
      }
    }

    this.dataSchema = null;
  }

  public DataRow getGlobalView()
  {
    return globalView;
  }

  public void dataRowChanged(final MasterDataRowChangeEvent chEvent)
  {
    // rebuild the global view and tracks changes ..
    final int type = chEvent.getType();
    if (type == MasterDataRowChangeEvent.COLUMN_ADDED)
    {
      globalView.putField(chEvent.getColumnName(), chEvent.getColumnValue(), false);
    }
    else if (type == MasterDataRowChangeEvent.COLUMN_UPDATED)
    {
      globalView.putField(chEvent.getColumnName(), chEvent.getColumnValue(), true);
    }
    else if (type == MasterDataRowChangeEvent.COLUMN_REMOVED)
    {
      globalView.removeColumn(chEvent.getColumnName());
    }
  }

  /**
   * This updates the global view.
   * todo
   */
  private void updateGlobalView()
  {
    if (parameterDataRow != null)
    {
      final String[] columnNames = parameterDataRow.getColumnNames();
      for (int i = 0; i < columnNames.length; i++)
      {
        final String columnName = columnNames[i];
        if (columnName != null)
        {
          final Object columnValue = parameterDataRow.get(columnName);
          globalView.putField(columnName, columnValue, true);
        }
      }
    }

    if (reportDataRow != null)
    {
      final int dataColCount = reportDataRow.getColumnCount();
      final boolean readable = reportDataRow.isReadable();
      for (int i = 0; i < dataColCount; i++)
      {
        final String columnName = reportDataRow.getColumnName(i);
        if (columnName != null)
        {
          if (readable)
          {
            final Object columnValue = reportDataRow.get(i);
            globalView.putField(columnName, columnValue, true);
          }
          else
          {
            globalView.putField(columnName, null, true);
          }
        }
      }
    }
  }

  public boolean isAdvanceable()
  {
    if (paddingDataRow != null)
    {
      if (prePaddingCount > 0)
      {
        return true;
      }

      if (paddingDataRow.getPrePaddingRows(globalView) > 0)
      {
        return true;
      }
      if (paddingDataRow.getPostPaddingRows(globalView) > 0)
      {
        return true;
      }
    }
    if (reportDataRow != null)
    {
      if (reportDataRow.isAdvanceable())
      {
        return true;
      }

      // at the end of the report, we should be also at the end of the columns ...
      if (paddingDataRow != null)
      {
        final int colsToGo = (paddingDataRow.getCrosstabColumnCount() - paddingDataRow.getCurrentCursorPosition()) - 1;
        if (colsToGo > 0)
        {
          prePaddingCount = colsToGo;
          return true;
        }
      }
    }
    return false;
  }

  public MasterDataRow derive()
  {
    final GlobalMasterRow o = new GlobalMasterRow();
    o.environmentDataRow = environmentDataRow;
    o.outputProcessorMetaData = outputProcessorMetaData;
    o.prePaddingCount = prePaddingCount;
    o.paddingDataRow = paddingDataRow;
    o.dataFactory = dataFactory;
    o.dataSchema = dataSchema;
    o.schemaCompiler = schemaCompiler;
    o.schemaDefinition = schemaDefinition;
    o.globalView = globalView.derive();
    o.reportDataRow = reportDataRow;
    o.parameterDataRow = parameterDataRow;
    o.resourceBundleFactory = resourceBundleFactory;
    o.expressionDataRow = expressionDataRow.derive(o, false);
    if (parentRow != null)
    {
      o.parentRow = parentRow.derive();
    }
    o.importedDataRow = importedDataRow;
    return o;
  }

  public void setImportedDataRow(final ImportedVariablesDataRow dataRow)
  {
    if (importedDataRow != null)
    {
      final String[] columnNames = importedDataRow.getColumnNames();
      for (int i = 0; i < columnNames.length; i++)
      {
        final String columnName = columnNames[i];
        if (columnName != null)
        {
          globalView.removeColumn(columnName);
        }
      }
    }

    this.importedDataRow = dataRow;
    if (importedDataRow != null)
    {
      final String[] columnNames = importedDataRow.getColumnNames();
      for (int i = 0; i < columnNames.length; i++)
      {
        final String columnName = columnNames[i];
        if (columnName != null)
        {
          final Object columnValue = importedDataRow.get(columnName);
          globalView.putField(columnName, columnValue, false);
        }
      }
    }

    this.dataSchema = null;
  }

  /**
   * The datarow that contains the values as imported from the subreport. Can be null
   *
   * @return the imported datarow.
   */
  public ImportedVariablesDataRow getImportedDataRow()
  {
    return importedDataRow;
  }

  public MasterDataRow getParentDataRow()
  {
    return parentRow;
  }

  /**
   * This advances the cursor by one row and updates the flags.
   *
   * @return
   */
  public MasterDataRow advance()
  {
    return advanceRecursively(false, null);
  }

  /**
   * This method is public as a implementation sideeffect. It is only intended to be used internally and no matter what
   * you intend: If you are not calling it from a MasterDataRow implementation, then you are on the wrong track.
   *
   * @param deepTraversingOnly
   * @param subReportRow
   * @return
   */
  public MasterDataRow advanceRecursively(final boolean deepTraversingOnly,
                                          final MasterDataRow subReportRow)
  {
    final GlobalMasterRow dataRow = new GlobalMasterRow();
    dataRow.environmentDataRow = environmentDataRow;
    dataRow.outputProcessorMetaData = outputProcessorMetaData;
    if (deepTraversingOnly == false)
    {
      dataRow.globalView = globalView.advance();
    }
    else
    {
      dataRow.globalView = globalView.derive();
    }
    dataRow.dataSchema = dataSchema;
    dataRow.dataFactory = dataFactory;
    dataRow.schemaCompiler = schemaCompiler;
    dataRow.schemaDefinition = schemaDefinition;
    dataRow.parameterDataRow = parameterDataRow;
    dataRow.resourceBundleFactory = resourceBundleFactory;
    boolean needActivate = false;
    if (deepTraversingOnly == false && paddingDataRow != null)
    {
      dataRow.paddingDataRow = paddingDataRow.advance();
      dataRow.prePaddingCount = prePaddingCount;
    }

    if (deepTraversingOnly == false && reportDataRow != null)
    {
      if (prePaddingCount > 0)
      {
        dataRow.prePaddingCount -= 1;
        dataRow.reportDataRow = reportDataRow;
        needActivate = true;
      }
      else
      {
        dataRow.reportDataRow = reportDataRow.advance();
      }
    }
    else
    {
      dataRow.reportDataRow = reportDataRow;
    }
    dataRow.updateGlobalView();
    if (expressionDataRow != null)
    {
      dataRow.expressionDataRow = expressionDataRow.derive(dataRow, true);
    }
    if (parentRow != null)
    {
      // the parent row should get a grip on our data as well - just for the
      // deep traversing fun and so on ..
      dataRow.parentRow = parentRow.advanceRecursively(true, dataRow);
    }

    if (importedDataRow != null)
    {
      if (subReportRow != null)
      {
        dataRow.importedDataRow = importedDataRow.refresh(subReportRow.getGlobalView(), subReportRow.getDataSchema());
        final String[] columnNames = dataRow.importedDataRow.getColumnNames();
        for (int i = 0; i < columnNames.length; i++)
        {
          final String columnName = columnNames[i];
          if (columnName != null)
          {
            final Object columnValue = dataRow.importedDataRow.get(columnName);
            dataRow.globalView.putField(columnName, columnValue, true);
          }
        }
      }
    }

    if (deepTraversingOnly == false && paddingDataRow != null)
    {
      if (needActivate)
      {
        dataRow.paddingDataRow.activate(dataRow);
      }
      else
      {
        dataRow.prePaddingCount = dataRow.paddingDataRow.getPostPaddingRows(dataRow.getGlobalView());
        if (dataRow.prePaddingCount > 0)
        {
          dataRow.paddingDataRow.activate(dataRow);
        }
      }
    }
    return dataRow;
  }

  public void fireReportEvent(final ReportEvent event)
  {
    if (expressionDataRow != null)
    {
      expressionDataRow.fireReportEvent(event);
    }
    if ((event.getType() & ReportEvent.NO_PARENT_PASSING_EVENT) == ReportEvent.NO_PARENT_PASSING_EVENT)
    {
      return;
    }
    if (parentRow != null)
    {
      final ReportState parentState = event.getState().getParentSubReportState();
      final ReportEvent deepEvent;
      if (parentState == null)
      {
        deepEvent = event;
      }
      else
      {
        deepEvent = new ReportEvent
            (parentState, event.getState(), event.getType() | ReportEvent.DEEP_TRAVERSING_EVENT);
      }
      parentRow.fireReportEvent(deepEvent);
      parentRow.updateImportedVariables(getGlobalView(), getDataSchema());
    }
  }

  public void updateImportedVariables(final DataRow globalView, final DataSchema dataSchema)
  {
    if (importedDataRow == null)
    {
      return;
    }

    // This advance is just an refresh ...
    importedDataRow = importedDataRow.refresh(globalView, dataSchema);
    final String[] columnNames = importedDataRow.getColumnNames();
    for (int i = 0; i < columnNames.length; i++)
    {
      final String columnName = columnNames[i];
      if (columnName != null)
      {
        final Object columnValue = importedDataRow.get(columnName);
        this.globalView.putField(columnName, columnValue, true);
      }
    }
  }

  public boolean isPrepareEventListener()
  {
    if (parentRow != null)
    {
      if (parentRow.isPrepareEventListener())
      {
        return true;
      }
    }

    if (expressionDataRow == null)
    {
      return false;
    }
    return expressionDataRow.isPrepareEventListener();
  }


  public MasterDataRow startCrosstabMode(final CrosstabSpecification crosstabSpecification)
  {
    final GlobalMasterRow retval = (GlobalMasterRow) derive();
    retval.paddingDataRow = new PaddingDataRow(crosstabSpecification);
    final int prePaddingRows = retval.paddingDataRow.getPrePaddingRows(retval.getGlobalView());
    if (prePaddingRows > 0)
    {
      // todo
      // The current position of the first data-row of this crosstab does point to the first computed column.
      // this means, we have to insert one or more artificial rows now.
//      DebugLog.log("PrePadding on StartCR: " + prePaddingRows);
      retval.paddingDataRow.activate(retval);
      retval.prePaddingCount = prePaddingRows;
    }
    return retval;
  }

  public MasterDataRow endCrosstabMode()
  {
    final GlobalMasterRow retval = (GlobalMasterRow) derive();
    retval.paddingDataRow = null;
    return retval;
  }

  public MasterDataRow resetRowCursor()
  {
    final GlobalMasterRow retval = (GlobalMasterRow) derive();
    if (retval.paddingDataRow != null)
    {
      retval.paddingDataRow = retval.paddingDataRow.resetRowCursor();

      final int prePaddingRows = retval.paddingDataRow.getPrePaddingRows(retval.getGlobalView());
      if (prePaddingRows > 0)
      {
        // The current position of the first data-row of this crosstab does point to the first computed column.
        // this means, we have to insert one or more artificial rows now.
//        DebugLog.log("PrePadding on StartCR: " + prePaddingRows);
        retval.paddingDataRow.activate(retval);
        retval.prePaddingCount = prePaddingRows;
      }
    }
    return retval;
  }

  public int getPrePaddingCount()
  {
    return prePaddingCount;
  }

  public MasterDataRow clearExportedParameters()
  {
    final GlobalMasterRow derived = (GlobalMasterRow) derive();
    derived.setImportedDataRow(null);
    derived.resetDataSchema();
    return derived;
  }

  public ResourceBundleFactory getResourceBundleFactory()
  {
    return resourceBundleFactory;
  }

  public void resetDataSchema()
  {
    this.dataSchema = null;
  }

  public GlobalMasterRow rebuild()
  {
    if (globalView.getColumnNames().length == 0)
    {
      return this;
    }

    if (parentRow != null)
    {
      throw new IllegalStateException
          ("This should be at the beginning of the master-report processing. No parent allowed.");
    }
    if (reportDataRow != null)
    {
      throw new IllegalStateException
          ("This should be at the beginning of the master-report processing. No report-data allowed.");
    }

    final GlobalMasterRow gmr = (GlobalMasterRow) derive();
    gmr.dataSchema = null;
    gmr.globalView = new FastGlobalView();
    gmr.parameterDataRow = null;
    gmr.setParameterDataRow(getParameterDataRow());
    return gmr;
  }

  public MasterDataRow updateDataSchema(final DataSchemaDefinition dataSchemaDefinition)
  {
    if (dataSchemaDefinition == null)
    {
      throw new NullPointerException();
    }

    final DefaultDataAttributeContext dac = new DefaultDataAttributeContext
        (outputProcessorMetaData, resourceBundleFactory.getLocale());
    final GlobalMasterRow gmr = (GlobalMasterRow) derive();
    gmr.schemaDefinition = dataSchemaDefinition;
    gmr.schemaCompiler = new ProcessingDataSchemaCompiler
        (dataSchemaDefinition, dac, schemaCompiler.getResourceManager(), schemaCompiler.getGlobalDefaults());
    gmr.dataSchema = null;
    return gmr;
  }

  public DataSchemaDefinition getDataSchemaDefinition()
  {
    return schemaDefinition;
  }

  public void refresh()
  {
    updateGlobalView();

    if (expressionDataRow != null)
    {
      expressionDataRow.refresh();
    }
  }
}
TOP

Related Classes of org.pentaho.reporting.engine.classic.core.states.datarow.GlobalMasterRow

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.