Package org.pentaho.reporting.engine.classic.extensions.toc

Source Code of org.pentaho.reporting.engine.classic.extensions.toc.IndexNumberGeneratorFunction

package org.pentaho.reporting.engine.classic.extensions.toc;

import java.util.ArrayList;
import java.util.Arrays;

import org.pentaho.reporting.engine.classic.core.Group;
import org.pentaho.reporting.engine.classic.core.RelationalGroup;
import org.pentaho.reporting.engine.classic.core.event.ReportEvent;
import org.pentaho.reporting.engine.classic.core.function.AbstractFunction;
import org.pentaho.reporting.engine.classic.core.function.Expression;
import org.pentaho.reporting.engine.classic.core.function.FunctionUtilities;
import org.pentaho.reporting.engine.classic.core.util.IntegerCache;

/**
* A data-collector that collects table-of-contents items at group-starts. The function
* collects these items accross subreport boundaries.
*
* @author Thomas Morgner.
*/
public class IndexNumberGeneratorFunction extends AbstractFunction
{
  private int depth;
  private ArrayList groupCount;
  private boolean collectDetails;

  private transient int groupIndex;
  private transient boolean initialized;

  /**
   * Creates an unnamed function. Make sure the name of the function is set using {@link #setName} before the function
   * is added to the report's function collection.
   */
  public IndexNumberGeneratorFunction()
  {
    this.groupIndex = -1;
  }

  public boolean isCollectDetails()
  {
    return collectDetails;
  }

  public void setCollectDetails(final boolean collectDetails)
  {
    this.collectDetails = collectDetails;
  }

  public int getDepth()
  {
    return depth;
  }

  public void setDepth(final int depth)
  {
    this.depth = depth;
  }

  /**
   * Receives notification that report generation initializes the current run. <P> The event carries a
   * ReportState.Started state.  Use this to initialize the report.
   *
   * @param event The event.
   */
  public void reportInitialized(final ReportEvent event)
  {
    if (event.isDeepTraversing())
    {
      return;
    }

    if (initialized == false)
    {
      initialized = true;

      groupCount = new ArrayList(depth);
    }
    groupCount.clear();
    groupIndex = -1;
  }

  /**
   * Receives notification that the report has started.
   *
   * @param event the event.
   */
  public void reportStarted(final ReportEvent event)
  {
    if (event.isDeepTraversing())
    {
      return;
    }

    groupIndex = -1;
  }

  public void groupStarted(final ReportEvent event)
  {
    if (event.isDeepTraversing())
    {
      if ("toc".equals(event.getOriginatingState().getReport().getMetaData().getName()))
      {
        return;
      }
    }

    groupIndex += 1;
    if (groupCount.size() == groupIndex)
    {
      // new level entered
      groupCount.add(IntegerCache.getInteger(1));
    }
    else
    {
      final int lastIndex = groupCount.size() - 1;
      if (lastIndex == groupIndex)
      {
        // existing level increased
        final Integer o = (Integer) groupCount.get(lastIndex);
        if (o == null)
        {
          throw new IllegalStateException();
        }
        groupCount.set(lastIndex, IntegerCache.getInteger(o.intValue() + 1));
      }
      else
      {
        throw new IllegalStateException("Out of index error: " + groupIndex + " " + groupCount.size());
      }
    }
  }

  /**
   * Receives notification that a group of item bands is about to be processed. <P> The next events will be
   * itemsAdvanced events until the itemsFinished event is raised.
   *
   * @param event The event.
   */
  public void itemsStarted(final ReportEvent event)
  {
    if (event.isDeepTraversing())
    {
      if ("toc".equals(event.getOriginatingState().getReport().getMetaData().getName()))
      {
        return;
      }
    }

    if (collectDetails)
    {
      groupIndex += 1;
    }
  }

  /**
   * Receives notification that a row of data is being processed.
   *
   * @param event the event.
   */
  public void itemsAdvanced(final ReportEvent event)
  {
    if (event.isDeepTraversing())
    {
      if ("toc".equals(event.getOriginatingState().getReport().getMetaData().getName()))
      {
        return;
      }
    }

    if (collectDetails)
    {
      if (groupIndex < depth || depth == 0)
      {
        if (groupCount.size() == groupIndex)
        {
          // new level entered
          groupCount.add(IntegerCache.getInteger(1));
        }
        else
        {
          final int lastIndex = groupCount.size() - 1;
          if (lastIndex == groupIndex)
          {
            // existing level increased
            final Integer o = (Integer) groupCount.get(lastIndex);
            if (o == null)
            {
              throw new IllegalStateException();
            }
            groupCount.set(lastIndex, IntegerCache.getInteger(o.intValue() + 1));
          }
          else
          {
            throw new IllegalStateException("Out of index error: " + groupIndex + " " + groupCount.size());
          }
        }
      }
    }
  }


  /**
   * Receives notification that a group of item bands has been completed. <P> The itemBand is finished, the report
   * starts to close open groups.
   *
   * @param event The event.
   */
  public void itemsFinished(final ReportEvent event)
  {
    if (event.isDeepTraversing())
    {
      if ("toc".equals(event.getOriginatingState().getReport().getMetaData().getName()))
      {
        return;
      }
    }

    if (collectDetails)
    {
      if ((groupIndex + 2) == groupCount.size())
      {
        groupCount.remove(groupCount.size() - 1);
      }
      groupIndex -= 1;
    }
  }

  /**
   * Receives notification that a group has finished.
   *
   * @param event the event.
   */
  public void groupFinished(final ReportEvent event)
  {
    super.groupFinished(event);
    if (event.isDeepTraversing())
    {
      if ("toc".equals(event.getOriginatingState().getReport().getMetaData().getName()))
      {
        return;
      }
    }

    final Group group = FunctionUtilities.getCurrentDeepTraverseGroup(event);
    if (group instanceof RelationalGroup == false)
    {
      return;
    }

    if ((groupIndex + 2) == groupCount.size())
    {
      groupCount.remove(groupCount.size() - 1);
    }
    groupIndex -= 1;
  }

  /**
   * Return the current expression value.
   * <p/>
   * The value depends (obviously) on the expression implementation.
   *
   * @return the value of the function.
   */
  public Object getValue()
  {
    final Integer[] indexValues = new Integer[groupCount.size()];
    for (int i = 0; i < indexValues.length; i++)
    {
      indexValues[i] = (Integer) this.groupCount.get(i);
    }
    return indexValues;
  }

  /**
   * Clones the expression.  The expression should be reinitialized after the cloning. <P> Expressions maintain no
   * state, cloning is done at the beginning of the report processing to disconnect the expression from any other object
   * space.
   *
   * @return a clone of this expression.
   * @throws CloneNotSupportedException this should never happen.
   */
  public Object clone() throws CloneNotSupportedException
  {
    final IndexNumberGeneratorFunction o = (IndexNumberGeneratorFunction) super.clone();
    if (groupCount != null)
    {
      o.groupCount = (ArrayList) groupCount.clone();
    }
    return o;
  }

  /**
   * Checks whether this expression is a deep-traversing expression. Deep-traversing expressions receive events from all
   * sub-reports. This returns false by default, as ordinary expressions have no need to be deep-traversing.
   *
   * @return false.
   */
  public boolean isDeepTraversing()
  {
    return true;
  }

  /**
   * Return a completly separated copy of this function. The copy does no longer share any changeable objects with the
   * original function.
   *
   * @return a copy of this function.
   */
  public Expression getInstance()
  {
    final IndexNumberGeneratorFunction instance = (IndexNumberGeneratorFunction) super.getInstance();
    instance.groupCount = null;
    return instance;
  }
}
TOP

Related Classes of org.pentaho.reporting.engine.classic.extensions.toc.IndexNumberGeneratorFunction

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.