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

  $Archive: /njcl_v2/src/com/novell/service/session/xplat/ConnectionSearchEnumerator.java $
  $Revision: 6 $
  $Modtime: 1/28/00 1:03p $

  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.xplat;

import com.novell.service.session.util.Debug;
import com.novell.service.jncp.NSIException;
import com.novell.service.jncp.NSIExceptionBuilder;
import com.novell.service.jncpv2.clx.ClxJNI;
import com.novell.service.jncpv2.cal.CalJNI;
import com.novell.service.jncpv2.net.NetJNI;
import com.novell.service.session.SessionAttr;
import com.novell.service.session.SessionAttrEnumerator;
import com.novell.service.session.SessionAttrs;
import com.novell.service.session.SessionEnv;
import com.novell.service.session.SessionException;
import com.novell.service.session.spi.SessionManagerImpl;
import com.novell.service.session.SessionManagerFactory;
import com.novell.service.session.SessionRuntimeException;
import com.novell.service.session.InvalidDomainNameException;
import com.novell.service.session.InvalidUserNameException;
import com.novell.service.session.util.TwoWayHashtable;
import com.novell.service.toolkit.jcl.NWLong;
import com.novell.service.toolkit.jcl.NWVersion;
import com.novell.java.lang.IntegerBuffer;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.NoSuchElementException;
import java.util.Vector;
import java.io.Serializable;

/** @internal
 * Utility class shared by NDS and Bindery Session providers.
 */
/*
 * Search cached connections only
 */
public class ConnectionSearchEnumerator extends ConnectionEnumerator 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  OPEN_CLOSE_CONN_DEBUG = false;
   final static private boolean  I_DEBUG = false; // Ignore exception
   final static private boolean  S_DEBUG = false; // May have side effects
   final static private boolean  CACHE_DEBUG = false;

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

   ConnectionSearchEnumerator(
      SessionAttrs matchingSessionAttrSet,
      Connections connections)
   throws SessionException
   {
      this(matchingSessionAttrSet, connections, true);
   }

   public ConnectionSearchEnumerator(
      SessionAttrs matchingSessionAttrSet,
      Connections connections,
      boolean match)
   throws SessionException
   {
      super(connections);
      this.attributesToMatch = matchingSessionAttrSet;
      this.matchMode = match;
      nextElement();
      this.firstScan = false;
   }

   /**
   * Inherited from ConnectionEnumerator
   *
   * @see ConnectionEnumerator#hasMoreElements
   */
   public boolean hasMoreElements()
   {
      return(null != this.lookAhead);
   }

   /**
    * Inherited from ConnectionEnumerator
    *
    * @see ConnectionEnumerator#nextElement
    */
   public Object nextElement()
   throws NoSuchElementException
   {
      return (doScanWork());
   }

   /**
    * Returns the next matching Connection.
    */
   private Object doScanWork()
   {
      Connection currentConnection = null, connectionToReturn;
      boolean found = true;

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

      connectionToReturn = this.lookAhead;
      this.lookAhead = null;

      // Iterate through sessions
      while (this.enum.hasMoreElements())
      {
         currentConnection = (Connection)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 = currentConnection.getAttributes(matchingIds);
            if (sessionAttrSet.matchesSubset(this.attributesToMatch))
            {
               this.lookAhead = currentConnection;
               break;
            }
         }
         catch (SessionException e)
         {
            if (I_DEBUG)
               com.novell.service.session.util.Debug.ignoreException(e);
         }
      }

      return (connectionToReturn);
   }
} // class ConnectionSearchEnumerator
