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

  $Archive: /njcl_v2rmi/src/com/novell/service/nds/naming/net/NetClassDefinitionsBindingEnumerator.java $
  $Revision: 6 $
  $Modtime: 1/05/01 3:59p $

  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.rmi.RemoteException;
import java.util.*;

import javax.naming.*;
import javax.naming.directory.*;

import com.sun.jndi.toolkit.ctx.*;

import com.novell.service.jncp.NSIException;
//import com.novell.service.jncpv2r.net.*;

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

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

import com.novell.utility.naming.spi.ContextFactory;


/** @internal
 * NamingEnumeration subclass setup specifically for
 * NetClassDefinitionsDirContext.  This will enumerate all
 * Class Definitions.
 */
class NetClassDefinitionsBindingEnumerator
   implements NamingEnumeration
{
   private static final String CLASSES_BINDING_NAME = "SC=Classes";

   private static ContextFactory factory;
   private static NdsNamingExceptionFactory exceptionFactory;


   static
   {
      factory = new SchemaContextFactory ();
      exceptionFactory = new NdsNamingExceptionFactory ();
   }


   private NetEnvironment environment;
   private int classAttributesLevel;

   private NetService service;
   private NetIterationHandle iterationHandle;
   private NetBuffer classNames;
   private NetReadClassDefBuffer classDefs;

   private Enumeration entries;


   /**
    * @param cassDefsContext     The NetClassDefinitionsDirContext
    *                            constructing this class.
    */
   public NetClassDefinitionsBindingEnumerator (
         NamingEnumeration enumeration,
         NetEnvironment environment)
      throws NamingException
   {
      try
      {
         this.environment = environment;
         service = environment.getService ();

         iterationHandle = new NetIterationHandle (
                                 service,
                                 NetJNI.DSV_READ_CLASS_DEF);

         classNames = new NetBuffer (
                                       service,
                                       NetJNI.DSV_READ_CLASS_DEF,
                                       environment.getBatchSize ());

         while (enumeration.hasMore ())
         {
            classNames.putClassName (
               ((NdsClassName) enumeration.next ()).getClassName ());
         }

         classDefs = new NetReadClassDefBuffer (
                        service,
                        NetJNI.DS_CLASS_DEFS,
                        environment.getBatchSize ());

         getClassDefs ();
      }
      catch (NSIException e)
      {
         NamingException ne = exceptionFactory.getNamingException (e);
         throw ne;
      }

   } /* ClassDefinitionsBindingEnumerator () */

   /**
    *
    */
   public boolean hasMoreElements ()
   {
      if (!entries.hasMoreElements () && !iterationHandle.moreIterations ())
      {
         return (false);
      }
      return (true);
   }

   public boolean hasMore ()
      throws NamingException
   {
      return (hasMoreElements ());
   }

   /**
    *
    */
   private void getClassDefs ()
      throws NSIException
   {
      try
      {
         service.readClassDef (
                        NetJNI.DS_CLASS_DEFS,
                        false,
                        classNames.getHandle (),
                        iterationHandle,
                        classDefs);

         entries = classDefs.getEntries ();
      }
      catch (SessionException e)
      {
         NSIException ne = new NSIException ();

         ne.setRootCause (e);
         throw (ne);
      }
      catch (RemoteException e)
      {
         NSIException ne = new NSIException ();

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

   } /* getClassDefs () */

   /**
    * Returns the next element in the classDefs buffer.  If the buffer is
    * empty, it attempts to refill it.
    */
   public Object nextElement ()
   {
      try
      {
         return (next ());
      }
      catch (NamingException e)
      {
         throw (new NoSuchElementException ());
      }
   }

   /**
    *
    */
   public Object next ()
      throws NamingException
   {
      if (!this.hasMoreElements ())
      {
         throw (new NoSuchElementException ());
      }

      try
      {
         if (!entries.hasMoreElements ())
         {
            // No more elements in this buffer, get next buffer
            getClassDefs ();
         }

         StringBuffer distinguishedName;

         // Get next element from this buffer
         NetClassInfo classInfo = (NetClassInfo) entries.nextElement ();

         distinguishedName = new StringBuffer (NetService.MAX_DN_CHARS);
         distinguishedName.append ("\"");
         distinguishedName.append (classInfo.getName ());
         distinguishedName.append ("\".");
         distinguishedName.append (CLASSES_BINDING_NAME);

         return (new Binding (
                        classInfo.getName (),
                        factory.getContextInstance (
                                    new String (distinguishedName),
                                    classInfo,
                                    environment)));
      }
      catch (NSIException e)
      {
         NamingException ne = exceptionFactory.getNamingException (e);
         throw (ne);
      }

   } /* next () */

   /**
    *
    */
   public void close ()
      throws NamingException
   {
      try
      {
         iterationHandle.closeIteration ();
      }
      catch (NSIException e)
      {
         NamingException ne = exceptionFactory.getNamingException (e);
         throw (ne);
      }
   }

} /* NetClassDefinitionsBindingEnumerator */
