
/* **************************************************************************

  $Archive: /njcl/src/com/novell/java/util/CompositeEnumerator.java $
  $Revision: 1 $
  $Modtime: 4/22/98 2:27p $
 
  Copyright (c) 1998 Novell, Inc.  All Rights Reserved.

  THIS WORK IS  SUBJECT  TO  U.S.  AND  INTERNATIONAL  COPYRIGHT  LAWS  AND
  TREATIES.   NO  PART  OF  THIS  WORK MAY BE  USED,  PRACTICED,  PERFORMED
  COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED,  ABRIDGED, CONDENSED,
  EXPANDED,  COLLECTED,  COMPILED,  LINKED,  RECAST, TRANSFORMED OR ADAPTED
  WITHOUT THE PRIOR WRITTEN CONSENT OF NOVELL, INC. ANY USE OR EXPLOITATION
  OF THIS WORK WITHOUT AUTHORIZATION COULD SUBJECT THE PERPETRATOR TO
  CRIMINAL AND CIVIL LIABILITY.

****************************************************************************/

package com.novell.java.util;


import java.util.Enumeration;
import java.util.NoSuchElementException;


/** @internal
 * Links two or more Enumerations so that they can be accessed as
 * one Enumeration.  When the last item of one enumeration is reached,
 * the next enumeration is started.
 *
 * <p>Note that any enumerations hooked together by this class must
 * allow the calling of hasMoreElements() more than once for each
 * hasMoreElements()/nextElement() iteration.
 *
 * <p>This is because the hasMoreElements() is called as part of the
 * implementation of nextElement().  This is because we can't rely on
 * the NoSuchElement exception marking the end of an enumeration.
 * </p>
 */
public class CompositeEnumerator implements Enumeration
{
   Enumeration[] list;
   int pos = 0;

   /**
    * Constructs a composite enumeration from two Enumeration instances.
    *
    * @param      enum1          (in) first enumeration.
    * @param      enum2          (in) second enumeration.
    */
   public CompositeEnumerator (Enumeration enum1, Enumeration enum2)
   {
      list = new Enumeration[2];

      list[0] = enum1;
      list[1] = enum2;
   }

   /**
    * Constructs a composite enumeration from an array of Enumeration
    * instances.
    *
    * @param      list           (in) array of enumeratios to link together.
    */
   public CompositeEnumerator (Enumeration[] list)
   {
      this.list = list;
   }

   /**
    * Tell whether or not the end of the composite enumeration has been
    * reached.
    *
    * <p>This method is implemented in such a manner that the
    * 'hasMoreElements()' method in the current enumeration is called once
    * and only once for each call to the 'hasMoreElements()' method of
    * the composite enumeration.
    * </p>
    *
    * @return                    true if the last element of the last
    *                            enumeration has not yet been reached; false
    *                            if it has been reached.  If the end of an
    *                            enumeration is reached, the next enumeration
    *                            is tried, and so forth, until an object is
    *                            returned, or until all enumerations have
    *                            been tried.
    */
   public boolean hasMoreElements ()
   {
      if (pos >= list.length)
         return (false);

      boolean hasMore = false;
      
      while (!hasMore)
      {
         hasMore = list[pos].hasMoreElements ();

         if (!hasMore && ++pos >= list.length)
            return (false);
      }
      return (hasMore);

   } /* hasMoreElements */

   /**
    * Return the next element of the composite enumeration.
    *
    * <p>This method is implemented in such a manner that the
    * 'nextElement()' method in the current enumeration is called once
    * and only once for each call to the 'nextElement()' method of
    * the composite enumeration.
    * </p>
    *
    * @return                    the next object in the composite
    *                            enumeration.  If the end of an enumeration
    *                            is reached, the next enumeration is tried,
    *                            and so forth, until an object is returned,
    *                            or until all enumerations have been tried.
    */
   public Object nextElement ()
   {
      if (hasMoreElements ())
      {
         return (list[pos].nextElement ());
      }
      else
      {
         throw new NoSuchElementException ();
      }
   }

} /* CompositeEnumerator */


