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

  $Archive: /njcl_v2/src/com/novell/service/session/SessionSearchEnumerator.java $
  $Revision: 13 $
  $Modtime: 8/26/99 2:11p $

  Copyright (c) 1997 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.service.session;

import java.util.Enumeration;
import java.util.NoSuchElementException;
import java.io.Serializable;

/**
 * Provides an implementation of SessionEnumerator that contains only
 * sessions that match a given search criteria.
 */
public class SessionSearchEnumerator extends SessionEnumerator implements Serializable
{
   // Always access debug via final static...hopefully a final static of
   // false will be optimized out by the compiler
   final static private boolean DEBUG = false;
   final static private boolean I_DEBUG = false; // Ignore exception
   final static private boolean S_DEBUG = false; // May have side effects

   private SessionAttrs attributesToMatch;
   private boolean matchMode;
   private Session lookAhead = null;
   private boolean firstScan = true;

 /**
  * Constructs a SessionSearchEnumerator object with the matchingSessionAttrSet
  * and sessionEnum parameters.
  *
  * @param matchingSessionAttrSet The matching attribute set passed in to
  *                               the constructor.
  * @param sessionEnum The passed in session enumeration.
  *
  * @exception SessionException Top-level exception extended by all Session
  *            exceptions and thrown by Session objects.
  */
   public SessionSearchEnumerator
   (
      SessionAttrs matchingSessionAttrSet,
      Enumeration sessionEnum
   )
   throws SessionException
   {
      this(matchingSessionAttrSet, sessionEnum, true);
   }

 /**
  * Constructs a SessionSearchEnumerator object with the matchingSessionAttrSet,
  * sessionEnum and match parameters.
  *
  * @param matchingSessionAttrSet The matching attribute set passed in to
  *                               the constructor.
  * @param sessionEnum The passed in session enumeration.
  * @param match A boolean set to TRUE if the session enumerators are
  *              matching, otherwise set to FALSE.
  *
  * @exception SessionException Top-level exception extended by all Session
  *            exceptions and thrown by Session objects.
  */
   public SessionSearchEnumerator
   (
      SessionAttrs matchingSessionAttrSet,
      Enumeration sessionEnum,
      boolean match
   )
   throws SessionException
   {
      super(sessionEnum);
      this.attributesToMatch = matchingSessionAttrSet;
      this.matchMode = match;
      nextElement();
      this.firstScan = false;
   }

  /**
    * @internal
    *
   * Determines if this enumeration contains more elements. This
   * hasMoreElements method is inherited from SessionEnumerator.
   *
   * @return A boolean set to TRUE if this enumeration contains more
   *         elements, otherwise set to FALSE.
   *
   * @see SessionEnumerator#hasMoreElements
   */
   public boolean hasMoreElements
   (
   )
   {
      return (null != this.lookAhead);
   }

  /**
    * @internal
    *
   * Returns the next element of this enumeration. This nextElement
   * method is inherited from SessionEnumerator.
   *
   * @return The next element of this enumeration.
   *
   * @exception NoSuchElementException Thrown if no more elements exist.
   *
   * @see SessionEnumerator#nextElement
   */
   public Object nextElement
   (
   )
   throws NoSuchElementException
   {
      return doScanWork();
   }

   /*
    * Returns the next matching Session.
    */
   private Object doScanWork
   (
   )
   {
      Session currentSession = null, sessionToReturn;
      boolean found = true;

      if ((null == this.lookAhead) && (!this.firstScan))
         throw new java.util.NoSuchElementException();

      sessionToReturn = this.lookAhead;
      this.lookAhead = null;

       // Iterate through sessions
      while (this.enum.hasMoreElements())
      {
         currentSession = (Session)this.enum.nextElement();
         try
         {
            // Only want to compare matching ids
            String[] matchingIds = new String[this.attributesToMatch.count()];
            int count = 0;
            SessionAttrEnumerator attrEnum = this.attributesToMatch.getAttributes();
            while (attrEnum.hasMoreElements())
            {
               matchingIds[count++] = attrEnum.next().getSessionAttrId();
            }

            SessionAttrs sessionAttrSet = currentSession.getAttributes(matchingIds);
            if (sessionAttrSet.matchesSubset(this.attributesToMatch))
            {
               this.lookAhead = currentSession;
               break;
            }
         }
         catch (Exception e)
         {
            if (I_DEBUG)
               com.novell.service.session.util.Debug.ignoreException(
                  "scan failure", e);
//            throw new java.util.NoSuchElementException(e.toString());
         }
      }

      return sessionToReturn;
   }
}

