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

Source Code of org.pentaho.reporting.engine.classic.core.util.LevelList$ElementLevelList

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

import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.TreeSet;

/**
* A list that associates a level (instance of <code>Integer</code>) with each element in the list.
*
* @author Thomas Morgner
*/
public class LevelList implements Cloneable
{
  /**
   * A static object array of size zero.
   */
  private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
  /**
   * A static object array of size zero.
   */
  private static final Integer[] EMPTY_INTEGER_ARRAY = new Integer[0];

  /**
   * Constant for level zero.
   */
  private static final Integer ZERO = new Integer(0);

  /**
   * A treeset to build the iterator.
   */
  private transient TreeSet iteratorSetAsc;

  /**
   * A treeset to build the iterator.
   */
  private transient TreeSet iteratorSetDesc;

  /**
   * A treeset to cache the level iterator.
   */
  private HashMap iteratorCache;

  /**
   * A comparator for levels in descending order.
   */
  private static final class DescendingComparator implements Comparator, Serializable
  {
    /**
     * Default constructor.
     */
    private DescendingComparator()
    {
    }

    /**
     * Compares its two arguments for order.  Returns a negative integer, zero, or a positive integer as the first
     * argument is less than, equal to, or greater than the second.<p>
     *
     * @param o1 the first object to be compared.
     * @param o2 the second object to be compared.
     * @return a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater
     *         than the second.
     * @throws ClassCastException if the arguments' types prevent them from being compared by this Comparator.
     */
    public int compare(final Object o1, final Object o2)
    {
      if ((o1 instanceof Comparable) == false)
      {
        throw new ClassCastException("Need comparable Elements");
      }
      if ((o2 instanceof Comparable) == false)
      {
        throw new ClassCastException("Need comparable Elements");
      }
      final Comparable c1 = (Comparable) o1;
      final Comparable c2 = (Comparable) o2;
      return -1 * c1.compareTo(c2);
    }
  }

  /**
   * An list that caches all elements for a certain level.
   */
  private static final class ElementLevelList
  {
    /**
     * The level list.
     */
    private Object[] data;

    /**
     * Creates an iterator that provides access to all the elements in a list at the specified level.
     *
     * @param list  the list (null not permitted).
     * @param level the level.
     */
    private ElementLevelList(final LevelList list, final int level)
    {
      if (list == null)
      {
        throw new NullPointerException();
      }

      final Object[] rawElements = list.getRawElements();
      final Integer[] rawLevels = list.getRawLevels();

      final ArrayList datalist = new ArrayList(rawElements.length);
      for (int i = 0; i < rawElements.length; i++)
      {
        final Object iNext = rawElements[i];
        final Integer iLevel = rawLevels[i];
        if (iLevel.intValue() == level)
        {
          datalist.add(iNext);
        }
      }
      data = datalist.toArray();
    }

    /**
     * Returns the data for this level as object array.
     *
     * @return the data for this level as object array.
     */
    protected Object[] getData()
    {
      return (Object[]) data.clone();
    }

    /**
     * Returns the data for this level as object array. Behaves like ArrayList.toArray(..)
     *
     * @param target object array that should receive the contents
     * @return the data for this level as object array.
     */
    protected Object[] getData(Object[] target)
    {
      if (target == null)
      {
        target = new Object[data.length];
      }
      else if (target.length < data.length)
      {
        target = (Object[]) Array.newInstance(target.getClass().getComponentType(), data.length);
      }
      System.arraycopy(data, 0, target, 0, data.length);
      if (target.length > data.length)
      {
        target[data.length] = null;
      }
      return target;
    }

    /**
     * Returns the size if the list.
     *
     * @return the size.
     */
    protected int size()
    {
      return data.length;
    }
  }

  /**
   * The elements.
   */
  private ArrayList elements;

  /**
   * The levels.
   */
  private ArrayList levels;

  /**
   * Creates a new list (initially empty).
   */
  public LevelList()
  {
    this.elements = new ArrayList();
    this.levels = new ArrayList();
    this.iteratorCache = new HashMap();
  }

  /**
   * Returns the number of elements in the list.
   *
   * @return the element count.
   */
  public int size()
  {
    return elements.size();
  }

  /**
   * Returns an iterator that iterates through the levels in ascending order.
   *
   * @return an iterator.
   */
  public Iterator getLevelsAscending()
  {
    if (iteratorSetAsc == null)
    {
      iteratorSetAsc = new TreeSet();
      final Integer[] ilevels = (Integer[]) levels.toArray(new Integer[levels.size()]);
      for (int i = 0; i < ilevels.length; i++)
      {
        if (iteratorSetAsc.contains(ilevels[i]) == false)
        {
          iteratorSetAsc.add(ilevels[i]);
        }
      }
    }
    return iteratorSetAsc.iterator();
  }

  /**
   * Returns the levels of the elements in the list in descending order.
   *
   * @return the levels in descending order.
   */
  public Integer[] getLevelsDescendingArray()
  {
    if (levels.isEmpty())
    {
      return LevelList.EMPTY_INTEGER_ARRAY;
    }
    if (iteratorSetDesc == null)
    {
      final Integer[] ilevels = (Integer[]) levels.toArray(new Integer[levels.size()]);
      iteratorSetDesc = new TreeSet(new DescendingComparator());
      for (int i = 0; i < ilevels.length; i++)
      {
        if (iteratorSetDesc.contains(ilevels[i]) == false)
        {
          iteratorSetDesc.add(ilevels[i]);
        }
      }
    }
    return (Integer[]) iteratorSetDesc.toArray(new Integer[iteratorSetDesc.size()]);
  }

  /**
   * Returns an iterator that iterates through the levels in descending order.
   *
   * @return an iterator.
   */
  public Iterator getLevelsDescending()
  {
    if (iteratorSetDesc == null)
    {
      iteratorSetDesc = new TreeSet(new DescendingComparator());
      final Integer[] ilevels = (Integer[]) levels.toArray(new Integer[levels.size()]);
      for (int i = 0; i < ilevels.length; i++)
      {
        if (iteratorSetDesc.contains(ilevels[i]) == false)
        {
          iteratorSetDesc.add(ilevels[i]);
        }
      }
    }
    return iteratorSetDesc.iterator();
  }

  /**
   * Returns the elements as an array.
   *
   * @return the array.
   */
  public Object[] toArray()
  {
    return elements.toArray();
  }

  /**
   * Returns an iterator for all the elements at a given level.
   *
   * @param level  the level.
   * @param target the target array that should receive the contentes
   * @return the data for the level as object array.
   */
  public Object[] getElementArrayForLevel(final int level, final Object[] target)
  {
    ElementLevelList it = (ElementLevelList)
        iteratorCache.get(IntegerCache.getInteger(level));
    if (it == null)
    {
      it = new ElementLevelList(this, level);
      iteratorCache.put(IntegerCache.getInteger(level), it);
    }
    if (target == null)
    {
      return it.getData();
    }
    else
    {
      return it.getData(target);
    }
  }

  /**
   * Returns an iterator for all the elements at a given level.
   *
   * @param level the level.
   * @return the data for the level as object array.
   */
  public Object[] getElementArrayForLevel(final int level)
  {
    return getElementArrayForLevel(level, null);
  }

  /**
   * Returns the numer of elements registered for an certain level.
   *
   * @param level the level that should be queried
   * @return the numer of elements in that level
   */
  public int getElementCountForLevel(final int level)
  {
    ElementLevelList it = (ElementLevelList) iteratorCache.get
        (IntegerCache.getInteger(level));
    if (it == null)
    {
      it = new ElementLevelList(this, level);
      iteratorCache.put(IntegerCache.getInteger(level), it);
    }
    return it.size();
  }

  /**
   * Creates an iterator for the elements in the list at the given level.
   *
   * @param level the level.
   * @return An iterator.
   * @deprecated use the array methods for best performance.
   */
  protected Iterator getElementsForLevel(final int level)
  {
    final List list = Arrays.asList(getElementArrayForLevel(level));
    return Collections.unmodifiableList(list).iterator();
  }


  /**
   * Returns the element with the given index.
   *
   * @param index the index.
   * @return the element.
   */
  public Object get(final int index)
  {
    return elements.get(index);
  }

  /**
   * Adds an element at level zero.
   *
   * @param o the element.
   */
  public void add(final Object o)
  {
    elements.add(o);
    levels.add(LevelList.ZERO);
    iteratorSetAsc = null;
    iteratorSetDesc = null;
    iteratorCache.remove(LevelList.ZERO);
  }

  /**
   * Adds an element at a given level.
   *
   * @param o     the element.
   * @param level the level.
   */
  public void add(final Object o, final int level)
  {
    elements.add(o);
    final Integer i = IntegerCache.getInteger(level);
    levels.add(i);
    iteratorCache.remove(i);
    iteratorSetAsc = null;
    iteratorSetDesc = null;
  }

  /**
   * Sets the level for an element.
   *
   * @param index the element index.
   * @param level the level.
   */
  public void setLevel(final int index, final int level)
  {
    levels.set(index, IntegerCache.getInteger(level));
  }

  /**
   * Returns the level for an element.
   *
   * @param index the element index.
   * @return the level.
   */
  public int getLevel(final int index)
  {
    return ((Integer) levels.get(index)).intValue();
  }

  /**
   * Returns the index of an element.
   *
   * @param o the element.
   * @return the index.
   */
  public int indexOf(final Object o)
  {
    return elements.indexOf(o);
  }

  /**
   * Returns the level of an element.
   *
   * @param o the element.
   * @return the level.
   */
  public int getLevel(final Object o)
  {
    return getLevel(indexOf(o));
  }

  /**
   * Sets the level of an element.
   *
   * @param o     the element.
   * @param level the level.
   */
  public void setLevel(final Object o, final int level)
  {
    setLevel(indexOf(o), level);
  }

  /**
   * Clones the list.
   *
   * @return the clone.
   * @throws CloneNotSupportedException should never happen.
   */
  public Object clone()
      throws CloneNotSupportedException
  {
    final LevelList l = (LevelList) super.clone();
    l.elements = (ArrayList) elements.clone();
    l.levels = (ArrayList) levels.clone();
    l.iteratorCache = (HashMap) iteratorCache.clone();
    return l;
  }

  /**
   * Clears the list.
   */
  public void clear()
  {
    elements.clear();
    levels.clear();
    iteratorCache.clear();
    iteratorSetAsc = null;
    iteratorSetDesc = null;
  }

  /**
   * Returns all stored objects as object array.
   *
   * @return all elements as object array.
   */
  protected Object[] getRawElements()
  {
    if (elements.isEmpty())
    {
      return LevelList.EMPTY_OBJECT_ARRAY;
    }
    return elements.toArray(new Object[elements.size()]);
  }

  /**
   * Returns all active levels as java.lang.Integer array.
   *
   * @return all levels as Integer array.
   */
  protected Integer[] getRawLevels()
  {
    if (levels.isEmpty())
    {
      return LevelList.EMPTY_INTEGER_ARRAY;
    }
    return (Integer[]) levels.toArray(new Integer[levels.size()]);
  }
}
TOP

Related Classes of org.pentaho.reporting.engine.classic.core.util.LevelList$ElementLevelList

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.