DesignTimeDataSchemaModel.java :  » Report » Pentaho-Reporting-3.6.1 » org » pentaho » reporting » engine » classic » core » designtime » Java Open Source

Java Open Source » Report » Pentaho Reporting 3.6.1 
Pentaho Reporting 3.6.1 » org » pentaho » reporting » engine » classic » core » designtime » DesignTimeDataSchemaModel.java
/*
 * 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) 2009 Pentaho Corporation..  All rights reserved.
 */

package org.pentaho.reporting.engine.classic.core.designtime;

import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;

import org.pentaho.reporting.engine.classic.core.AbstractReportDefinition;
import org.pentaho.reporting.engine.classic.core.AttributeNames;
import org.pentaho.reporting.engine.classic.core.CompoundDataFactory;
import org.pentaho.reporting.engine.classic.core.DataFactory;
import org.pentaho.reporting.engine.classic.core.MasterReport;
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.ReportEnvironmentDataRow;
import org.pentaho.reporting.engine.classic.core.ReportProcessingException;
import org.pentaho.reporting.engine.classic.core.Section;
import org.pentaho.reporting.engine.classic.core.SubReport;
import org.pentaho.reporting.engine.classic.core.function.Expression;
import org.pentaho.reporting.engine.classic.core.states.QueryDataRowWrapper;
import org.pentaho.reporting.engine.classic.core.states.datarow.EmptyTableModel;
import org.pentaho.reporting.engine.classic.core.states.datarow.StaticDataRow;
import org.pentaho.reporting.engine.classic.core.util.CloseableTableModel;
import org.pentaho.reporting.engine.classic.core.wizard.DataAttributeContext;
import org.pentaho.reporting.engine.classic.core.wizard.DataSchema;
import org.pentaho.reporting.engine.classic.core.wizard.DataSchemaCompiler;
import org.pentaho.reporting.engine.classic.core.wizard.DataSchemaDefinition;
import org.pentaho.reporting.engine.classic.core.wizard.DataSchemaModel;
import org.pentaho.reporting.engine.classic.core.wizard.DataSchemaUtility;
import org.pentaho.reporting.engine.classic.core.wizard.DefaultDataAttributeContext;
import org.pentaho.reporting.engine.classic.core.wizard.DefaultDataSchema;
import org.pentaho.reporting.engine.classic.core.wizard.DefaultDataSchemaModel;
import org.pentaho.reporting.libraries.base.util.DebugLog;
import org.pentaho.reporting.libraries.base.util.LinkedMap;
import org.pentaho.reporting.libraries.base.util.ObjectUtilities;

/**
 * Todo: Document Me
 *
 * @author Thomas Morgner
 */
public class DesignTimeDataSchemaModel implements DataSchemaModel
{
  private AbstractReportDefinition parent;
  private long parentChangeTracker;
  private long masterChangeTracker;
  private DataSchema dataSchema;
  private DataSchemaDefinition dataSchemaDefinition;
  private DataAttributeContext dataAttributeContext;
  private MasterReport masterReportElement;
  private String[] columnNames;
  private static final String[] EMPTY_NAMES = new String[0];
  private String query;
  private Throwable dataFactoryException;


  public DesignTimeDataSchemaModel(final MasterReport masterReportElement,
                                   final AbstractReportDefinition report)
  {
    if (masterReportElement == null)
    {
      throw new NullPointerException();
    }
    if (report == null)
    {
      throw new NullPointerException();
    }
    this.columnNames = EMPTY_NAMES;
    this.query = report.getQuery();
    this.masterReportElement = masterReportElement;
    this.parent = report;
    this.parentChangeTracker = -1;
    this.masterChangeTracker = -1;

    this.dataSchemaDefinition = masterReportElement.getDataSchemaDefinition();
    if (this.dataSchemaDefinition == null)
    {
      this.dataSchemaDefinition = DataSchemaUtility.parseDefaults
          (masterReportElement.getResourceManager());
    }
    this.dataAttributeContext = new DefaultDataAttributeContext();
  }

  public DataAttributeContext getDataAttributeContext()
  {
    return dataAttributeContext;
  }

  public AbstractReportDefinition getParent()
  {
    return parent;
  }

  public boolean isValid()
  {
    ensureDataSchemaValid();
    return dataFactoryException == null;
  }

  public DataSchema getDataSchema()
  {
    ensureDataSchemaValid();

    return dataSchema;
  }

  private void ensureDataSchemaValid()
  {
    if (dataSchema == null ||
        parentChangeTracker != parent.getNonVisualsChangeTracker() ||
        masterChangeTracker != masterReportElement.getNonVisualsChangeTracker() ||
        ObjectUtilities.equal(this.query, parent.getQuery()) == false)
    {

      this.query = parent.getQuery();
      try
      {
        this.dataFactoryException = null;
        this.dataSchema = buildDataSchema();
      }
      catch (Throwable e)
      {
        handleError(e);
        this.dataSchema = new DefaultDataSchema();
        this.dataFactoryException = e;
      }
      masterChangeTracker = masterReportElement.getNonVisualsChangeTracker();
      parentChangeTracker = parent.getNonVisualsChangeTracker();
    }
  }

  protected void handleError(final Throwable e)
  {
    DebugLog.log("Failure", e);
  }

  public Throwable getDataFactoryException()
  {
    return dataFactoryException;
  }

  private DataSchema buildDataSchema()
  {
    this.columnNames = EMPTY_NAMES;
    this.dataFactoryException = null;

    final ParameterDataRow parameterRow;
    if (parent instanceof MasterReport)
    {
      final MasterReport mr = (MasterReport) parent;
      final LinkedMap values = DefaultDataSchemaModel.computeParameterValueSet(mr);
      parameterRow = new ParameterDataRow((String[]) values.keys(new String[values.size()]), values.values());
    }
    else if (parent instanceof SubReport)
    {
      final SubReport sr = (SubReport) parent;
      final ParameterMapping[] inputMappings = sr.getInputMappings();
      final Object[] values = new Object[inputMappings.length];
      final String[] names = new String[inputMappings.length];
      for (int i = 0; i < inputMappings.length; i++)
      {
        final ParameterMapping inputMapping = inputMappings[i];
        names[i] = inputMapping.getAlias();
      }
      parameterRow = new ParameterDataRow(names, values);
    }
    else
    {
      parameterRow = new ParameterDataRow();
    }

    final Expression[] expressions = parent.getExpressions().getExpressions();
    final DataSchemaCompiler dataSchemaCompiler =
        new DataSchemaCompiler(dataSchemaDefinition, dataAttributeContext, masterReportElement.getResourceManager());

    try
    {
      final CompoundDataFactory dataFactory = createDataFactory(parent);
      final MasterReport masterReport = masterReportElement;

      dataFactory.initialize(masterReport.getConfiguration(), masterReport.getResourceManager(),
          masterReport.getContentBase(), MasterReport.computeAndInitResourceBundleFactory
              (masterReport.getResourceBundleFactory(), masterReport.getReportEnvironment()));

      dataFactory.open();
      try
      {
        final TableModel reportData;
        if (parent.getQuery() == null)
        {
          reportData = new EmptyTableModel();
        }
        else
        {
          reportData = dataFactory.queryData
              (parent.getQuery(), new QueryDataRowWrapper(new StaticDataRow(), 1, getQueryTimeout(parent)));
        }
        final DataSchema dataSchema = dataSchemaCompiler.compile
            (reportData, expressions, parameterRow, masterReport.getReportEnvironment());
        this.columnNames = collectColumnNames(reportData, parameterRow, expressions);
        if (reportData instanceof CloseableTableModel)
        {
          final CloseableTableModel ctm = (CloseableTableModel) reportData;
          ctm.close();
        }
        return dataSchema;
      }
      finally
      {
        dataFactory.close();
      }
    }
    catch (final ReportDataFactoryException rdfe)
    {
      final TableModel reportData = new DefaultTableModel();
      final DataSchema dataSchema = dataSchemaCompiler.compile
          (reportData, expressions, parameterRow, masterReportElement.getReportEnvironment());
      this.columnNames = collectColumnNames(reportData, parameterRow, expressions);
      this.dataFactoryException = rdfe;
      return dataSchema;
    }
    catch (ReportProcessingException e)
    {
      final TableModel reportData = new DefaultTableModel();
      final DataSchema dataSchema = dataSchemaCompiler.compile
          (reportData, expressions, parameterRow, masterReportElement.getReportEnvironment());
      this.columnNames = collectColumnNames(reportData, parameterRow, expressions);
      this.dataFactoryException = e;
      return dataSchema;
    }
  }

  private CompoundDataFactory createDataFactory(AbstractReportDefinition reportDefinition)
      throws ReportDataFactoryException
  {
    final CompoundDataFactory cdf = new CompoundDataFactory();
    while (reportDefinition != null)
    {
      final DataFactory dataFactory = reportDefinition.getDataFactory();
      if (dataFactory != null)
      {
        cdf.add(dataFactory);
      }
      final Section parentSection = reportDefinition.getParentSection();
      if (parentSection == null)
      {
        reportDefinition = null;
      }
      else
      {
        reportDefinition = (AbstractReportDefinition) parentSection.getReportDefinition();
      }
    }

    return CompoundDataFactory.normalize(cdf);
  }

  private int getQueryTimeout(final AbstractReportDefinition report)
  {
    final Object o = report.getAttribute(AttributeNames.Internal.NAMESPACE,
        AttributeNames.Internal.DESIGN_TIME_QUERY_TIMEOUT);
    if (o instanceof Integer)
    {
      final Integer integer = (Integer) o;
      return integer.intValue();
    }
    return report.getQueryTimeout();
  }

  private String[] collectColumnNames(final TableModel reportData,
                                      final ParameterDataRow parameterRow,
                                      final Expression[] expressions)
  {

    final LinkedMap columnNamesCollector = new LinkedMap();

    final LinkedMap envCols = ReportEnvironmentDataRow.createEnvironmentMapping();
    final Object[] envColArray = envCols.values();
    for (int i = 0; i < envColArray.length; i++)
    {
      final String name = (String) envColArray[i];
      columnNamesCollector.put(name, Boolean.TRUE);
    }

    final String[] strings = parameterRow.getColumnNames();
    for (int i = 0; i < strings.length; i++)
    {
      final String string = strings[i];
      columnNamesCollector.put(string, Boolean.TRUE);
    }

    final int count = reportData.getColumnCount();
    for (int i = 0; i < count; i++)
    {
      columnNamesCollector.put(reportData.getColumnName(i), Boolean.TRUE);
    }
    for (int i = 0; i < expressions.length; i++)
    {
      final Expression expression = expressions[i];
      final String name = expression.getName();
      if (name != null)
      {
        columnNamesCollector.put(name, Boolean.TRUE);
      }
    }
    return (String[]) columnNamesCollector.keys(new String[columnNamesCollector.size()]);
  }

  public String[] getColumnNames()
  {
    ensureDataSchemaValid();

    return (String[]) columnNames.clone();
  }

  public boolean isSelectedDataSource(final DataFactory dataFactory,
                                      final String queryName)
  {
    ensureDataSchemaValid();

    AbstractReportDefinition reportDefinition = this.getParent();
    while (reportDefinition != null)
    {
      final DataFactory reportDataFactory = reportDefinition.getDataFactory();
      if (reportDataFactory != null)
      {
        if (findDataFactory(reportDataFactory, dataFactory, queryName))
        {
          return true;
        }
      }
      final Section parentSection = reportDefinition.getParentSection();
      if (parentSection == null)
      {
        reportDefinition = null;
      }
      else
      {
        reportDefinition = (AbstractReportDefinition) parentSection.getReportDefinition();
      }
    }

    return false;
  }

  private boolean findDataFactory(final DataFactory hayStack,
                                  final DataFactory needle,
                                  final String queryName)
  {
    if (hayStack == needle)
    {
      return ObjectUtilities.equal(queryName, query);
    }
    if (hayStack instanceof CompoundDataFactory == false)
    {
      return false;
    }
    final CompoundDataFactory cdf = (CompoundDataFactory) hayStack;
    final int size = cdf.size();
    for (int i = 0; i < size; i++)
    {
      final DataFactory dataFactory = cdf.getReference(i);
      if (findDataFactory(dataFactory, needle, queryName))
      {
        return true;
      }
    }
    return false;
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.