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 - 2009 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.engine.classic.core.metadata.DataFactoryRegistry;
import org.pentaho.reporting.libraries.base.config.Configuration;
import org.pentaho.reporting.libraries.base.util.LinkedMap;
import org.pentaho.reporting.libraries.resourceloader.ResourceKey;
import org.pentaho.reporting.libraries.resourceloader.ResourceManager;

/**
* 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 implements Cloneable, DataFactory
{
  private ArrayList<DataFactory> dataFactories;

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

  public void initialize(final Configuration configuration,
                         final ResourceManager resourceManager,
                         final ResourceKey contextKey,
                         final ResourceBundleFactory resourceBundleFactory)
  {
    for (int i = 0; i < dataFactories.size(); i++)
    {
      final DataFactory dataFactory = dataFactories.get(i);
      dataFactory.initialize(configuration, resourceManager, contextKey, resourceBundleFactory);
    }
  }

  public void open() throws ReportDataFactoryException
  {

  }

  /**
   * 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 TableModel queryData(final String query, final DataRow parameters) throws ReportDataFactoryException
  {
    if (parameters == null)
    {
      throw new NullPointerException();
    }
    if (query == null)
    {
      throw new NullPointerException();
    }

    for (int i = 0; i < dataFactories.size(); i++)
    {
      final DataFactory dataFactory = dataFactories.get(i);
      if ((isFreeFormQueryDataFactory(dataFactory) == false) && dataFactory.isQueryExecutable(query, parameters))
      {
        return dataFactory.queryData(query, parameters);
      }
    }
    for (int i = 0; i < dataFactories.size(); i++)
    {
      final DataFactory dataFactory = dataFactories.get(i);

      if (isFreeFormQueryDataFactory(dataFactory) && dataFactory.isQueryExecutable(query, parameters))
      {
        return dataFactory.queryData(query, parameters);
      }
    }
    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 DataFactoryRegistry registry = DataFactoryRegistry.getInstance();
    final String metaDataKey = dataFactory.getClass().getName();
    if (registry.isRegistered(metaDataKey) == false)
    {
      // assume the worst ..
      return true;
    }

    final DataFactoryMetaData metaData = registry.getMetaData(metaDataKey);
    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 = (CompoundDataFactory) clone();
    cdf.dataFactories = (ArrayList<DataFactory>) dataFactories.clone();
    cdf.dataFactories.clear();
    for (int i = 0; i < dataFactories.size(); i++)
    {
      final DataFactory dataFactory = dataFactories.get(i);
      cdf.dataFactories.add(dataFactory.derive());
    }
    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 boolean isQueryExecutable(final String query, final DataRow parameters)
  {
    for (int i = 0; i < dataFactories.size(); i++)
    {
      final DataFactory dataFactory = dataFactories.get(i);
      if ((isFreeFormQueryDataFactory(dataFactory) == false) && dataFactory.isQueryExecutable(query, parameters))
      {
        return true;
      }
    }
    for (int i = 0; i < dataFactories.size(); i++)
    {
      final DataFactory dataFactory = dataFactories.get(i);
      if ((isFreeFormQueryDataFactory(dataFactory)) && dataFactory.isQueryExecutable(query, parameters))
      {
        return true;
      }
    }
    return false;
  }

  /**
   * Creates and returns a copy of this object.
   *
   * @return a clone.
   */
  public Object clone()
  {
    try
    {
      return super.clone();
    }
    catch (CloneNotSupportedException e)
    {
      throw new IllegalStateException(e);
    }
  }

  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) throws ReportDataFactoryException
  {
    if (factory == null)
    {
      throw new NullPointerException();
    }
    final DataFactory derived = factory.derive();
    if (derived == null)
    {
      throw new ReportDataFactoryException(
          "Deriving failed silently. Fix your implementation of " + factory.getClass());
    }
    dataFactories.add(index, derived);
  }

  public void set(final int index, final DataFactory factory) throws ReportDataFactoryException
  {
    if (factory == null)
    {
      throw new NullPointerException();
    }
    final DataFactory derived = factory.derive();
    if (derived == null)
    {
      throw new ReportDataFactoryException(
          "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 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);
  }

  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;
    }

    final CompoundDataFactory retval = new CompoundDataFactory();
    final int size = cdf.size();
    for (int i = 0; i < size; i++)
    {
      final DataFactory original = cdf.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 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 void cancelRunningQuery()
  {
    // TODO implement
  }

  protected 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 CompoundDataFactory)
      {
        final CompoundDataFactory cdf = (CompoundDataFactory) 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, false);
    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.