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

  $Archive: /njcl_v2/src/com/novell/service/nds/naming/net/NetPartitionEnumerator.java $
  $Revision: 5 $
  $Modtime: 1/28/00 12:42p $
 
  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.service.nds.naming.net;


import java.util.*;
import javax.naming.*;

import com.novell.service.jncp.*;
import com.novell.service.nds.NdsSyntaxId;
import com.novell.service.toolkit.jcl.NWInteger;

import com.novell.service.session.SessionException;
import com.novell.service.jncpv2.net.*;

import com.novell.service.nds.naming.NdsNamingExceptionFactory;

/** @internal
 *
 *  NetPartitionEnumerator class.
 */
public class NetPartitionEnumerator implements Enumeration
{
   private String startObject;
   private NetService service;

   private NetIterationHandle iterationHandle;
   private NWInteger partCount;
   private NetBuffer partInfo;

   private boolean moreParts;
   private static NdsNamingExceptionFactory exceptionFactory =
       new NdsNamingExceptionFactory ();

    /**
     *  Constructs a NdsPartitionEnumerator object.
     *
     *  @param netEnv           Reference to NetEnvironment object.
     *  @param startObjectDN    FDN of the object from which the search starts.
     *
     *  @exception NSIException
     */
   protected NetPartitionEnumerator(
                     NetService service,
                     String startObjectDN)
       throws NSIException
   {
      this.startObject = startObjectDN;
      this.service = service;

      /* setup working environment */
      this.iterationHandle = new NetIterationHandle(
            service, NetJNI.DSV_SEARCH);
      this.partInfo = new NetBuffer(service);

      this.partCount = new NWInteger(0);
      this.moreParts = true;
   }

    /**
     * Read some values of the attribute from NDS.
     */
   private void getPartitions()
       throws NSIException
   {
      if (!this.moreParts)
         return;

      /* Search NDS to grab as many NDS objects whose "Object Class"
      ** are "Partition" as possible at a time.
      */

      /* setup search buffer */
      NetBuffer search = new NetBuffer(service,
                        NetJNI.DSV_SEARCH_FILTER,
                        NetJNI.DEFAULT_MESSAGE_LEN);

      /* setup search filter */
      NetFilter filter = new NetFilter(service);
      filter.addFilterToken(NetJNI.FTOK_ANAME, "Object Class",
                              NdsSyntaxId.CLASS_NAME_ID);

      filter.addFilterToken(NetJNI.FTOK_EQ);

      filter.addFilterToken(NetJNI.FTOK_AVAL, "Partition",
                              NdsSyntaxId.CLASS_NAME_ID);

      filter.addFilterToken(NetJNI.FTOK_END);

      filter.putFilter(search);

      NWInteger   objectCount = new NWInteger(0);

      /* searching... */
      try
      {
         service.search (
                            this.startObject,
                            NetJNI.DS_SEARCH_SUBTREE,
                            false,
                            search.getHandle(),
                            0, false, 0,
                            this.iterationHandle, 0, objectCount,
                            partInfo.getHandle());
      }
      catch (SessionException e)
      {
         NSIException ne = new NSIException ();

         ne.setRootCause (e);
         throw (ne);
      }

      moreParts = this.iterationHandle.moreIterations();
      partCount.setValue(partInfo.getObjectCount());
   }

    /**
     * Tests if this enumeration contains more elements.
     */
   public boolean hasMoreElements()
   {
       try {
          if (this.partCount.getValue() == 0)
             this.getPartitions();
       }
       catch (NSIException e) {
          this.partCount.setValue(0);
       }

      return this.partCount.getValue() != 0;
   }

    /**
     * Returns the next element of this enumeration.
     */
   public Object nextElement()
       throws NoSuchElementException
   {
      try {
         if (this.partCount.getValue () == 0)
            this.getPartitions();
      }
      catch (NSIException e) {
         throw new NoSuchElementException(e.getMessage());
      }

      /* if no more objects found from searching NDS, signal the caller */
      if (this.partCount.getValue() == 0)
         throw new NoSuchElementException();

      /* retrieve the object name from the cache, one at a time */
      StringBuffer partName = new StringBuffer();

      try {
         NetObjectInfo objectInfo = new NetObjectInfo();
         NWInteger   attrCount = new NWInteger(0);

         this.partInfo.getObjectName(partName, attrCount, objectInfo);
      }
      catch (NSIException e) {
         throw new NoSuchElementException(e.getMessage());
      }

      /* decrease the number of the objects */
      this.partCount.setValue(this.partCount.getValue() - 1);

      return partName.toString();
   }

	/**
	 * Closes the iteration handle for this NamingEnumeration.
	 */
	public void closeIteration ()
	   throws NamingException
	{
		try
		{
			iterationHandle.closeIteration ();
		}
      catch (NSIException e)
      {
         NamingException ne = exceptionFactory.getNamingException (e);
         throw (ne);
      }
	}
	
}