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

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

/*
* 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 java.util.ArrayList;

import org.pentaho.reporting.engine.classic.core.DataFactory;
import org.pentaho.reporting.engine.classic.core.ParameterDataRow;
import org.pentaho.reporting.engine.classic.core.ParameterMapping;
import org.pentaho.reporting.engine.classic.core.ReportDataFactoryException;
import org.pentaho.reporting.engine.classic.core.ReportProcessingException;
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.Expression;
import org.pentaho.reporting.engine.classic.core.function.ProcessingContext;
import org.pentaho.reporting.engine.classic.core.parameters.ParameterDefinitionEntry;
import org.pentaho.reporting.engine.classic.core.states.crosstab.CrosstabSpecification;
import org.pentaho.reporting.engine.classic.core.util.IntegerCache;
import org.pentaho.reporting.engine.classic.core.util.ReportParameterValues;
import org.pentaho.reporting.engine.classic.core.wizard.DataSchema;
import org.pentaho.reporting.engine.classic.core.wizard.DataSchemaDefinition;
import org.pentaho.reporting.libraries.base.util.FastStack;

/**
* Creation-Date: 20.02.2006, 15:30:21
*
* @author Thomas Morgner
*/
public final class DefaultFlowController
{
  private static class ReportDataContext
  {
    private boolean advanceRequested;

    protected ReportDataContext(final boolean advanceRequested)
    {
      this.advanceRequested = advanceRequested;
    }

    public boolean isAdvanceRequested()
    {
      return advanceRequested;
    }
  }

  private MasterDataRow dataRow;
  private boolean advanceRequested;
  private FastStack expressionsStack;
  private FastStack dataContextStack;
  private String exportDescriptor;
  private ProcessingContext reportContext;
  private ReportParameterValues parameters;

  public DefaultFlowController(final ProcessingContext reportContext,
                               final DataSchemaDefinition schemaDefinition,
                               final ReportParameterValues parameters,
                               final ParameterDefinitionEntry[] parameterDefinitionEntries,
                               final boolean includeStructuralPreprocessing) throws ReportDataFactoryException
  {
    if (reportContext == null)
    {
      throw new NullPointerException();
    }
    if (parameters == null)
    {
      throw new NullPointerException();
    }
    if (schemaDefinition == null)
    {
      throw new NullPointerException();
    }

    this.reportContext = reportContext;
    this.exportDescriptor = reportContext.getExportDescriptor();
    this.expressionsStack = new FastStack(10);
    this.dataContextStack = new FastStack(10);
    this.advanceRequested = false;
    this.parameters = parameters;

    this.dataRow = GlobalMasterRow.createReportRow
        (reportContext, schemaDefinition, new ParameterDataRow(parameters), parameterDefinitionEntries, includeStructuralPreprocessing);
  }

  private DefaultFlowController(final DefaultFlowController fc,
                                final MasterDataRow dataRow)
  {
    if (dataRow == null)
    {
      throw new NullPointerException();
    }
    this.reportContext = fc.reportContext;
    this.exportDescriptor = fc.exportDescriptor;
    this.dataContextStack = (FastStack) fc.dataContextStack.clone();
    this.expressionsStack = (FastStack) fc.expressionsStack.clone();
    this.advanceRequested = fc.advanceRequested;
    this.dataRow = dataRow;
    this.parameters = fc.parameters;
  }

  public DefaultFlowController derive()
  {
    return new DefaultFlowController(this, dataRow.derive());
  }

  public DefaultFlowController performAdvance()
  {
    if (dataRow.isAdvanceable() && advanceRequested == false)
    {
      final DefaultFlowController fc = new DefaultFlowController(this, dataRow);
      fc.advanceRequested = true;
      return fc;
    }
    return this;
  }

  public DefaultFlowController performCommit()
  {
    if (isAdvanceRequested())
    {
      final DefaultFlowController fc = new DefaultFlowController(this, dataRow);
      fc.dataRow = dataRow.advance();
      fc.advanceRequested = false;
      return fc;
    }
    return this;
  }

  public MasterDataRow getMasterRow()
  {
    return dataRow;
  }

  public boolean isAdvanceRequested()
  {
    return advanceRequested;
  }

  /**
   * This should be called only once per report processing. A JFreeReport object defines the global master report - all
   * other reports are subreport instances.
   * <p/>
   * The global master report receives its parameter set from the Job-Definition, while subreports will read their
   * parameters from the current datarow state.
   *
   * @param query
   * @param queryLimit
   * @param queryTimeout
   * @return
   * @throws ReportDataFactoryException
   */
  public DefaultFlowController performQuery(final DataFactory dataFactory,
                                            final String query,
                                            final int queryLimit,
                                            final int queryTimeout,
                                            final ResourceBundleFactory resourceBundleFactory)
      throws ReportDataFactoryException
  {
    if (dataFactory == null)
    {
      throw new NullPointerException();
    }
    if (resourceBundleFactory == null)
    {
      throw new NullPointerException();
    }

    final MasterDataRow masterRowWithoutData =
        dataRow.deriveSubDataRow(reportContext, dataFactory, new ParameterDataRow(parameters),
            dataRow.getParameterDefinitionEntries(), resourceBundleFactory);
    final ReportDataRow tableData;
    if (query != null)
    {
      tableData = ReportDataRow.createDataRow
          (masterRowWithoutData.getDataFactory(), query, queryLimit, queryTimeout,
              masterRowWithoutData.getGlobalView());
    }
    else
    {
      tableData = new ReportDataRow(new EmptyTableModel());
    }
    final MasterDataRow masterRow = masterRowWithoutData.deriveWithQueryData(tableData);

    final DefaultFlowController fc = new DefaultFlowController(this, masterRow);
    fc.dataContextStack.push(new ReportDataContext(advanceRequested));
    fc.dataRow = masterRow;
    fc.dataRow.resetDataSchema();
    return fc;
  }

  public DefaultFlowController performInitSubreport(final DataFactory dataFactory,
                                                    final ParameterMapping[] inputParameters,
                                                    final ResourceBundleFactory resourceBundleFactory)
  {
    if (dataFactory == null)
    {
      throw new NullPointerException();
    }
    if (inputParameters == null)
    {
      throw new NullPointerException();
    }
    if (resourceBundleFactory == null)
    {
      throw new NullPointerException();
    }

    // create a view for the parameters of the report ...
    final MasterDataRow subReportDataRow;
    if (isGlobalImportOrExport(inputParameters))
    {
      final ParameterDataRow parameterRow = new ParameterDataRow(dataRow.getGlobalView());
      subReportDataRow = dataRow.deriveSubDataRow(reportContext, dataFactory, parameterRow, null, resourceBundleFactory);
    }
    else
    {
      final ParameterDataRow parameterRow = new ParameterDataRow(inputParameters, dataRow.getGlobalView());
      subReportDataRow = dataRow.deriveSubDataRow(reportContext, dataFactory, parameterRow, null, resourceBundleFactory);
    }

    final DefaultFlowController fc = new DefaultFlowController(this, subReportDataRow);
    fc.dataContextStack.push(new ReportDataContext(advanceRequested));
    fc.dataRow = subReportDataRow;
    fc.dataRow.resetDataSchema();
    return fc;
  }


  public DefaultFlowController performSubReportQuery(final String query,
                                                     final int queryLimit,
                                                     final int queryTimeout,
                                                     final ParameterMapping[] outputParameters)
      throws ReportDataFactoryException
  {
    if (outputParameters == null)
    {
      throw new NullPointerException();
    }

    final MasterDataRow subReportDataRow = this.dataRow;
    // perform the query ...
    // add the resultset ...
    final ReportDataRow tableData;
    if (query != null)
    {
      tableData = ReportDataRow.createDataRow
          (subReportDataRow.getDataFactory(), query, queryLimit, queryTimeout, subReportDataRow.getGlobalView());
    }
    else
    {
      tableData = new ReportDataRow(new EmptyTableModel());
    }
    final MasterDataRow masterRow = subReportDataRow.deriveWithQueryData(tableData);

    if (isGlobalImportOrExport(outputParameters))
    {
      if ("true".equals(reportContext.getConfiguration().getConfigProperty
          ("org.pentaho.reporting.engine.classic.core.EnableGlobalSubReportImports")))
      {
        masterRow.getParentDataRow().setImportedDataRow(new ImportedVariablesDataRow(masterRow));
      }
      else
      {
        masterRow.getParentDataRow().setImportedDataRow
            (new ImportedVariablesDataRow(masterRow, filterGlobalImport(outputParameters)));
      }
    }
    else
    {
      // check and rebuild the parameter mapping from the inner to the outer
      // context. Only deep-traversal expressions will be able to see these
      // values (unless they have been defined as local variables).
      masterRow.getParentDataRow().setImportedDataRow(new ImportedVariablesDataRow(masterRow, outputParameters));
    }

    final DefaultFlowController fc = new DefaultFlowController(this, masterRow);
    fc.dataContextStack.push(new ReportDataContext(advanceRequested));
    fc.dataRow = masterRow;
    fc.dataRow.resetDataSchema();
    return fc;
  }

  private ParameterMapping[] filterGlobalImport(final ParameterMapping[] parameterMapping)
  {
    final ArrayList filteredList = new ArrayList(parameterMapping.length);
    for (int i = 0; i < parameterMapping.length; i++)
    {
      final ParameterMapping mapping = parameterMapping[i];
      if ("*".equals(mapping.getName()) &&
          "*".equals(mapping.getAlias()))
      {
        continue;
      }
      filteredList.add(mapping);
    }
    return (ParameterMapping[]) filteredList.toArray(new ParameterMapping[filteredList.size()]);
  }

  /**
   * Checks whether a global import is defined. A global import effectly overrides all other imports.
   *
   * @return true, if there is a global import defined, false otherwise.
   */
  private boolean isGlobalImportOrExport(final ParameterMapping[] inputParameters)
  {
    for (int i = 0; i < inputParameters.length; i++)
    {
      final ParameterMapping inputParameter = inputParameters[i];
      if ("*".equals(inputParameter.getName()) &&
          "*".equals(inputParameter.getAlias()))
      {
        return true;
      }
    }
    return false;
  }

  public DefaultFlowController activateExpressions(final Expression[] expressions,
                                                   final boolean preserveState)
      throws ReportProcessingException
  {
    if (expressions == null)
    {
      throw new NullPointerException();
    }

    final MasterDataRow dataRow = this.dataRow.derive();
    final ExpressionDataRow edr = dataRow.getExpressionDataRow();
    edr.pushExpressions(expressions, preserveState);
    dataRow.resetDataSchema();

    final DefaultFlowController fc = new DefaultFlowController(this, dataRow);
    final Integer exCount = IntegerCache.getInteger(expressions.length);
    fc.expressionsStack.push(exCount);
    return fc;
  }

  public DefaultFlowController deactivateExpressions()
  {
    final Integer counter = (Integer) this.expressionsStack.peek();
    final int counterRaw = counter.intValue();
    if (counterRaw == 0)
    {
      final DefaultFlowController fc = new DefaultFlowController(this, dataRow);
      fc.expressionsStack.pop();
      return fc;
    }

    final MasterDataRow dataRow = this.dataRow.derive();
    final ExpressionDataRow edr = dataRow.getExpressionDataRow();

    final DefaultFlowController fc = new DefaultFlowController(this, dataRow);
    fc.expressionsStack.pop();
    edr.popExpressions(counterRaw);
    dataRow.resetDataSchema();
    return fc;
  }

  public DefaultFlowController performReturnFromQuery()
  {
    final ReportDataRow reportDataRow = dataRow.getReportDataRow();
    if (reportDataRow == null)
    {
      return this;
    }
    // We dont close the report data, as some previously saved states may
    // still reference it. (The caching report data factory takes care of
    // that later.)

    final MasterDataRow innerDr = dataRow.deriveWithReturnFromQuery();
    final DefaultFlowController fc = new DefaultFlowController(this, innerDr);
    final ReportDataContext context = (ReportDataContext) fc.dataContextStack.pop();
    fc.dataRow = dataRow.getParentDataRow();
    fc.dataRow = fc.dataRow.derive();
    fc.advanceRequested = context.isAdvanceRequested();
    innerDr.resetDataSchema();
    return fc;
  }

  public DefaultFlowController performReturnFromSubreport()
  {
    // first, we undo the call "performSubreportQuery" and unwrap the report-data (and its corresponding stack entry)
    final MasterDataRow innerDrFromQuery = dataRow.deriveWithReturnFromQuery();
    final DefaultFlowController fc = new DefaultFlowController(this, innerDrFromQuery);
    final ReportDataContext context = (ReportDataContext) fc.dataContextStack.pop();
    fc.dataRow = fc.dataRow.derive();
    fc.advanceRequested = context.isAdvanceRequested();

    // second, we undo the call "performInitSubreport" and unwrap the parameter-data (and its corresponding stack entry)
    final MasterDataRow innerDr = fc.dataRow.deriveWithReturnFromQuery();
    final DefaultFlowController fc2 = new DefaultFlowController(fc, innerDr);
    final ReportDataContext context2 = (ReportDataContext) fc2.dataContextStack.pop();
    fc2.dataRow = dataRow.getParentDataRow();
    fc2.dataRow = fc2.dataRow.derive();
    fc2.advanceRequested = context2.isAdvanceRequested();
    innerDr.resetDataSchema();
    return fc2;
  }

  public DefaultFlowController performClearExportedParameters()
  {
    final ImportedVariablesDataRow exportedDataRow = dataRow.getImportedDataRow();
    if (exportedDataRow == null)
    {
      return this;
    }

    return new DefaultFlowController(this, dataRow.clearExportedParameters());
  }

  public String getExportDescriptor()
  {
    return exportDescriptor;
  }

  public ProcessingContext getReportContext()
  {
    return reportContext;
  }

  public DefaultFlowController fireReportEvent(final ReportEvent event)
  {
    dataRow.fireReportEvent(event);
    return this;
  }

  public int getCursor()
  {
    if (dataRow.getReportDataRow() != null)
    {
      return dataRow.getReportDataRow().getCursor();
    }
    return 0;
  }

  public DataSchema getDataSchema()
  {
    return dataRow.getDataSchema();
  }

  public DataFactory getDataFactory()
  {
    return dataRow.getDataFactory();
  }

  public DefaultFlowController startCrosstabMode(final CrosstabSpecification crosstabSpecification)
  {
    final MasterDataRow dataRow = this.dataRow.startCrosstabMode(crosstabSpecification);
    // begin crosstab mode ...
    return new DefaultFlowController(this, dataRow);
  }

  public DefaultFlowController endCrosstabMode()
  {
    final MasterDataRow dataRow = this.dataRow.endCrosstabMode();

    // end crosstab mode ...
    return new DefaultFlowController(this, dataRow);
  }

  public int getCurrentCrosstabPaddingItem()
  {
    return dataRow.getPrePaddingCount();
  }

  public DefaultFlowController resetRowCursor()
  {
    final MasterDataRow dataRow = this.dataRow.resetRowCursor();
    return new DefaultFlowController(this, dataRow);
  }

  public DefaultFlowController restart()
  {
    final GlobalMasterRow innerDr = dataRow.rebuild();
    return new DefaultFlowController(this, innerDr);
  }

  public DefaultFlowController updateDataSchema(final DataSchemaDefinition dataSchemaDefinition)
  {
    return new DefaultFlowController(this, dataRow.updateDataSchema(dataSchemaDefinition));
  }
}
TOP

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

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.