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

Source Code of org.pentaho.reporting.engine.classic.core.CompoundDataFactory

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

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

import java.util.ArrayList;
import javax.swing.table.TableModel;

import org.pentaho.reporting.engine.classic.core.metadata.DataFactoryMetaData;
import org.pentaho.reporting.libraries.base.util.ArgumentNullException;
import org.pentaho.reporting.libraries.base.util.LinkedMap;

/**
* The compound data factory is a collection of data-factories. Each of the child datafactories is queried in the order
* of their addition to the collection.
*
* @author Thomas Morgner
*/
public class CompoundDataFactory extends AbstractDataFactory implements CompoundDataFactorySupport
{
  private ArrayList<DataFactory> dataFactories;

  public CompoundDataFactory()
  {
    dataFactories = new ArrayList<DataFactory>();
  }

  public void initialize(final DataFactoryContext dataFactoryContext) throws ReportDataFactoryException
  {
    super.initialize(dataFactoryContext);
    for (int i = 0; i < dataFactories.size(); i++)
    {
      final DataFactory dataFactory = dataFactories.get(i);
      dataFactory.initialize(dataFactoryContext);
    }
  }

  /**
   * Queries a datasource. The string 'query' defines the name of the query. The Parameterset given here may contain
   * more data than actually needed for the query.
   * <p/>
   * The parameter-dataset may change between two calls, do not assume anything, and do not hold references to the
   * parameter-dataset or the position of the columns in the dataset.
   *
   * @param query      the query string
   * @param parameters the parameters for the query
   * @return the result of the query as table model.
   * @throws ReportDataFactoryException if an error occured while performing the query.
   */
  public final TableModel queryData(final String query, final DataRow parameters) throws ReportDataFactoryException
  {
    ArgumentNullException.validate("query", query);
    ArgumentNullException.validate("parameters", parameters);

    final TableModel staticResult = queryStatic(query, parameters);
    if (staticResult != null)
    {
      return staticResult;
    }
    final TableModel freeFormResult = queryFreeForm(query, parameters);
    if (freeFormResult != null)
    {
      return freeFormResult;
    }
    return handleFallThrough(query);
  }


  public TableModel queryDesignTimeStructureFreeForm(final String query,
                                                     final DataRow parameters) throws ReportDataFactoryException
  {
    return postProcess(query, parameters, queryDesignTimeStructFreeFormInternal(query, parameters));
  }

  private TableModel queryDesignTimeStructFreeFormInternal(final String query,
                                                           final DataRow parameters) throws ReportDataFactoryException
  {
    for (int i = 0; i < dataFactories.size(); i++)
    {
      final DataFactory dataFactory = dataFactories.get(i);

      if (dataFactory instanceof CompoundDataFactorySupport)
      {
        final CompoundDataFactorySupport support = (CompoundDataFactorySupport) dataFactory;
        if (support.isFreeFormQueryExecutable(query, parameters))
        {
          return support.queryDesignTimeStructureFreeForm(query, parameters);
        }
      }
      else if (isFreeFormQueryDataFactory(dataFactory) && dataFactory.isQueryExecutable(query, parameters))
      {
        if (dataFactory instanceof DataFactoryDesignTimeSupport) {
          DataFactoryDesignTimeSupport dts = (DataFactoryDesignTimeSupport) dataFactory;
          return dts.queryDesignTimeStructure(query, parameters);
        }
        else {
          return dataFactory.queryData(query, new DataRowWrapper(parameters));
        }
      }
    }
    return null;
  }

  public TableModel queryFreeForm(final String query, final DataRow parameters) throws ReportDataFactoryException
  {
    return postProcess(query, parameters, queryFreeFormInternal(query, parameters));
  }

  private TableModel queryFreeFormInternal(final String query,
                                           final DataRow parameters) throws ReportDataFactoryException
  {
    for (int i = 0; i < dataFactories.size(); i++)
    {
      final DataFactory dataFactory = dataFactories.get(i);

      if (dataFactory instanceof CompoundDataFactorySupport)
      {
        final CompoundDataFactorySupport support = (CompoundDataFactorySupport) dataFactory;
        if (support.isFreeFormQueryExecutable(query, parameters))
        {
          return support.queryFreeForm(query, parameters);
        }
      }
      else if (isFreeFormQueryDataFactory(dataFactory) && dataFactory.isQueryExecutable(query, parameters))
      {
        return dataFactory.queryData(query, parameters);
      }
    }
    return null;
  }

  public TableModel queryDesignTimeStructureStatic(final String query,
                                                   final DataRow parameters) throws ReportDataFactoryException
  {
    return postProcess(query, parameters, queryDesignTimeStructStaticInternal(query, parameters));
  }

  private TableModel queryDesignTimeStructStaticInternal(final String query,
                                                         final DataRow parameters) throws ReportDataFactoryException
  {
    for (int i = 0; i < dataFactories.size(); i++)
    {
      final DataFactory dataFactory = dataFactories.get(i);
      if (dataFactory instanceof CompoundDataFactorySupport)
      {
        final CompoundDataFactorySupport support = (CompoundDataFactorySupport) dataFactory;
        if (support.isStaticQueryExecutable(query, parameters))
        {
          return support.queryDesignTimeStructureStatic(query, parameters);
        }
      }
      else if ((isFreeFormQueryDataFactory(dataFactory) == false) && dataFactory.isQueryExecutable(query, parameters))
      {
        if (dataFactory instanceof DataFactoryDesignTimeSupport) {
          DataFactoryDesignTimeSupport dts = (DataFactoryDesignTimeSupport) dataFactory;
          return dts.queryDesignTimeStructure(query, parameters);
        }
        else {
          return dataFactory.queryData(query, new DataRowWrapper(parameters));
        }
      }
    }
    return null;
  }

  public TableModel queryStatic(final String query, final DataRow parameters) throws ReportDataFactoryException
  {
    return postProcess(query, parameters, queryStaticInternal(query, parameters));
  }

  protected TableModel postProcess(final String query, final DataRow parameters, final TableModel tableModel)
  {
    return tableModel;
  }

  private TableModel queryStaticInternal(final String query, final DataRow parameters) throws ReportDataFactoryException
  {
    for (int i = 0; i < dataFactories.size(); i++)
    {
      final DataFactory dataFactory = dataFactories.get(i);
      if (dataFactory instanceof CompoundDataFactorySupport)
      {
        final CompoundDataFactorySupport support = (CompoundDataFactorySupport) dataFactory;
        if (support.isStaticQueryExecutable(query, parameters))
        {
          return support.queryStatic(query, parameters);
        }
      }
      else if ((isFreeFormQueryDataFactory(dataFactory) == false) && dataFactory.isQueryExecutable(query, parameters))
      {
        return dataFactory.queryData(query, parameters);
      }
    }
    return null;
  }

  public TableModel queryDesignTimeStructure(final String query,
                                             final DataRow parameters) throws ReportDataFactoryException
  {
    ArgumentNullException.validate("query", query);
    ArgumentNullException.validate("parameters", parameters);

    final TableModel staticResult = queryStatic(query, parameters);
    if (staticResult != null)
    {
      return staticResult;
    }
    final TableModel freeFormResult = queryFreeForm(query, parameters);
    if (freeFormResult != null)
    {
      return freeFormResult;
    }
    return handleFallThrough(query);
  }


  protected TableModel handleFallThrough(final String query)
      throws ReportDataFactoryException
  {
    throw new ReportDataFactoryException("None of the data-factories was able to handle this query.");
  }

  private boolean isFreeFormQueryDataFactory(final DataFactory dataFactory)
  {
    final DataFactoryMetaData metaData = dataFactory.getMetaData();
    if (metaData.isFreeFormQuery())
    {
      return true;
    }

    return false;
  }

  /**
   * Returns a copy of the data factory that is not affected by its anchestor and holds no connection to the anchestor
   * anymore. A data-factory will be derived at the beginning of the report processing.
   *
   * @return a copy of the data factory.
   */
  public DataFactory derive()
  {
    final CompoundDataFactory cdf = deriveEmpty();

    for (int i = 0; i < dataFactories.size(); i++)
    {
      final DataFactory dataFactory = dataFactories.get(i);
      cdf.dataFactories.add(dataFactory.derive());
    }
    return cdf;
  }

  public CompoundDataFactory deriveEmpty()
  {
    final CompoundDataFactory cdf = (CompoundDataFactory) clone();
    cdf.dataFactories = (ArrayList<DataFactory>) dataFactories.clone();
    cdf.dataFactories.clear();
    return cdf;
  }

  /**
   * Closes the data factory and frees all resources held by this instance.
   */
  public void close()
  {
    for (int i = 0; i < dataFactories.size(); i++)
    {
      final DataFactory dataFactory = dataFactories.get(i);
      dataFactory.close();
    }
  }

  /**
   * Checks whether the query would be executable by this datafactory. This performs a rough check, not a full query.
   *
   * @param query      query name.
   * @param parameters the parameters for the query.
   * @return true, if the query may be executable, false, if no datasource claims the query.
   */
  public final boolean isQueryExecutable(final String query, final DataRow parameters)
  {
    return isStaticQueryExecutable(query, parameters) || isFreeFormQueryExecutable(query, parameters);
  }

  public boolean isFreeFormQueryExecutable(final String query,
                                           final DataRow parameters)
  {
    for (int i = 0; i < dataFactories.size(); i++)
    {
      final DataFactory dataFactory = dataFactories.get(i);
      if (dataFactory instanceof CompoundDataFactorySupport)
      {
        final CompoundDataFactorySupport support = (CompoundDataFactorySupport) dataFactory;
        if (support.isFreeFormQueryExecutable(query, parameters))
        {
          return true;
        }
      }
      else if ((isFreeFormQueryDataFactory(dataFactory)) && dataFactory.isQueryExecutable(query, parameters))
      {
        return true;
      }
    }
    return false;
  }

  public boolean isStaticQueryExecutable(final String query, final DataRow parameters)
  {
    for (int i = 0; i < dataFactories.size(); i++)
    {
      final DataFactory dataFactory = dataFactories.get(i);
      if (dataFactory instanceof CompoundDataFactorySupport)
      {
        final CompoundDataFactorySupport support = (CompoundDataFactorySupport) dataFactory;
        if (support.isStaticQueryExecutable(query, parameters))
        {
          return true;
        }
      }
      else if ((isFreeFormQueryDataFactory(dataFactory) == false) && dataFactory.isQueryExecutable(query, parameters))
      {
        return true;
      }
    }
    return false;
  }

  protected void addRaw(final DataFactory factory)
  {
    if (factory == null)
    {
      throw new NullPointerException();
    }
    dataFactories.add(factory);
  }

  public void add(final DataFactory factory)
  {
    if (factory == null)
    {
      throw new NullPointerException();
    }
    final DataFactory derived = factory.derive();
    if (derived == null)
    {
      throw new IllegalStateException("Deriving failed silently. Fix your implementation of " + factory.getClass());
    }
    dataFactories.add(derived);
  }

  public void add(final int index, final DataFactory factory)
  {
    if (factory == null)
    {
      throw new NullPointerException();
    }
    final DataFactory derived = factory.derive();
    if (derived == null)
    {
      throw new InvalidReportStateException(
          "Deriving failed silently. Fix your implementation of " + factory.getClass());
    }
    dataFactories.add(index, derived);
  }

  public void set(final int index, final DataFactory factory)
  {
    if (factory == null)
    {
      throw new NullPointerException();
    }
    final DataFactory derived = factory.derive();
    if (derived == null)
    {
      throw new InvalidReportStateException(
          "Deriving failed silently. Fix your implementation of " + factory.getClass());
    }
    dataFactories.set(index, derived);
  }

  public void remove(final int index)
  {
    dataFactories.remove(index);
  }

  public void remove(final DataFactory dataFactory)
  {
    dataFactories.remove(dataFactory);
  }

  public int size()
  {
    return dataFactories.size();
  }

  public DataFactory get(final int idx)
  {
    final DataFactory df = dataFactories.get(idx);
    return df.derive();
  }

  public int indexOfByReference(final DataFactory d)
  {
    for (int i = 0; i < size(); i++)
    {
      final DataFactory df = getReference(i);
      if (df == d)
      {
        return i;
      }
    }
    return -1;
  }

  public DataFactory getReference(final int idx)
  {
    return dataFactories.get(idx);
  }

  public boolean isNormalized()
  {
    for (int i = 0; i < dataFactories.size(); i++)
    {
      final DataFactory dataFactory = dataFactories.get(i);
      if (dataFactory instanceof CompoundDataFactory)
      {
        return false;
      }
    }
    return true;
  }

  public static CompoundDataFactory normalize(final DataFactory dataFactory)
  {
    return normalize(dataFactory, true);
  }

  protected CompoundDataFactory normalizeInternal(boolean derive)
  {
    final CompoundDataFactory retval = deriveEmpty();
    final int size = size();
    for (int i = 0; i < size; i++)
    {
      final DataFactory original = getReference(i);
      if (original instanceof CompoundDataFactory)
      {
        final CompoundDataFactory container = normalize(original, derive);
        final int containerSize = container.size();
        for (int x = 0; x < containerSize; x++)
        {
          if (derive)
          {
            retval.add(container.getReference(x));
          }
          else
          {
            retval.addRaw(container.getReference(x));
          }
        }
      }
      else
      {
        if (derive)
        {
          retval.add(original);
        }
        else
        {
          retval.addRaw(original);
        }

      }
    }
    return retval;
  }

  public static CompoundDataFactory normalize(final DataFactory dataFactory,
                                              final boolean derive)
  {
    if (dataFactory == null)
    {
      return new CompoundDataFactory();
    }

    if (dataFactory instanceof CompoundDataFactory == false)
    {
      final CompoundDataFactory retval = new CompoundDataFactory();
      if (derive)
      {
        retval.add(dataFactory);
      }
      else
      {
        retval.addRaw(dataFactory);
      }
      return retval;
    }

    final CompoundDataFactory cdf = (CompoundDataFactory) dataFactory;
    if (cdf.isNormalized())
    {
      if (derive)
      {
        return (CompoundDataFactory) cdf.derive();
      }
      return cdf;
    }

    return cdf.normalizeInternal(derive);
  }

  public String[] getQueryNames()
  {
    final LinkedMap nameSet = new LinkedMap();
    for (int i = 0; i < dataFactories.size(); i++)
    {
      final DataFactory dataFactory = dataFactories.get(i);
      final String[] queryNames = dataFactory.getQueryNames();
      for (int j = 0; j < queryNames.length; j++)
      {
        final String queryName = queryNames[j];
        nameSet.put(queryName, queryName);
      }
    }
    return (String[]) nameSet.keys(new String[nameSet.size()]);
  }

  public DataFactory getDataFactoryForQuery(final String queryName, final boolean freeform)
  {
    final DataRow dr = new StaticDataRow();
    for (int i = 0; i < size(); i++)
    {
      final DataFactory df = dataFactories.get(i);
      if (df instanceof CompoundDataFactorySupport)
      {
        final CompoundDataFactorySupport cdf = (CompoundDataFactorySupport) df;
        final DataFactory r = cdf.getDataFactoryForQuery(queryName, freeform);
        if (r != null)
        {
          return r;
        }
      }
      if ((isFreeFormQueryDataFactory(df) == freeform) && df.isQueryExecutable(queryName, dr))
      {
        return df;
      }
    }
    return null;
  }

  public DataFactory getDataFactoryForQuery(final String queryName)
  {
    final DataFactory nonFreeForm = getDataFactoryForQuery(queryName, false);
    if (nonFreeForm != null)
    {
      return nonFreeForm;
    }

    final DataFactory freeForm = getDataFactoryForQuery(queryName, true);
    if (freeForm != null)
    {
      return freeForm;
    }

    return null;
  }

}
TOP

Related Classes of org.pentaho.reporting.engine.classic.core.CompoundDataFactory

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.