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

  $Archive: /njcl_v2rmi/src/com/novell/service/nds/naming/net/NetSyntaxDefinitionsDirContext.java $
  $Revision: 9 $
  $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.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.nds.naming.*;

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


/** @internal
* This class is bound to the root of the schema tree and has bindings
* to all NDS Syntax definitions.
*
* @see JNDI documentation section 5.2.4 Schema
*/
public class NetSyntaxDefinitionsDirContext
      extends NetSchemaContainerDirContext
{
   /**
    * Constructor.
    *
    * @param objectName    Distinguished name of this object
    * @param baseClass     NDS class name
    * @param environment properties to be set in this objects environment
    */
   protected NetSyntaxDefinitionsDirContext (
         String objectName,
         String baseClass,
         NetEnvironment environment)
      throws NamingException
   {
      super (objectName, baseClass, environment);
   }

   /* ***********************************************************************
    * protected toolkit Context methods
    ************************************************************************/

   /**
    * Lists all NDS Syntax Definitions for current session
    */
   protected NamingEnumeration schema_list (
         Continuation cont)
      throws NamingException
   {
      cont.setSuccess ();
      return new SyntaxDefinitionsNameClassEnumerator (this);
   }

   /**
    * Lists all NDS Syntax Definitions for current session
    */
   protected NamingEnumeration schema_listBindings (
         Continuation cont)
      throws NamingException
   {
      cont.setSuccess ();
      return new SyntaxDefinitionsBindingEnumerator (this);
   }

   /**
    * Can't create new Syntax def's
    */
   protected void schema_bind (
         String name,
         Object obj,
         Continuation cont)
      throws NamingException
   {
      cont.setError (this, name);
      throw cont.fillInException (new OperationNotSupportedException ());
   }

   /**
    * Can't create new Syntax def's
    */
   protected void schema_rebind (
         String name,
         Object obj,
         Continuation cont)
      throws NamingException
   {
      cont.setError (this, name);
      throw cont.fillInException (new OperationNotSupportedException ());
   }

   /**
    * Can't remove Syntax def's
    */
   protected void schema_unbind (
         String name,
         Continuation cont)
      throws NamingException
   {
      cont.setError (this, name);
      throw cont.fillInException (new OperationNotSupportedException ());
   }

   /**
    * Can't rename Syntax def's
    */
   protected void schema_rename (
         String oldName,
         Name newName,
         Continuation cont)
      throws NamingException
   {
      cont.setError (this, newName);
      throw cont.fillInException (new OperationNotSupportedException ());
   }

   /**
    * Can't remove Syntax def's
    */
   protected void schema_destroySubcontext (
         String name,
         Continuation cont)
      throws NamingException
   {
      cont.setError (this, name);
      throw cont.fillInException (new OperationNotSupportedException ());
   }

   /**
    * Can't create Syntax def's
    */
   protected Context schema_createSubcontext (
         String name,
         Continuation cont)
      throws NamingException
   {
      cont.setError (this, name);
      throw cont.fillInException (new OperationNotSupportedException ());
   }

   /* ***********************************************************************
    * protected toolkit DirContext methods
    ************************************************************************/

   /**
    * Can't create Syntax def's
    */
   protected void schema_bind (
         String name,
         Object obj,
         Attributes attrs,
         Continuation cont)
      throws NamingException
   {
      cont.setError (this, name);
      throw cont.fillInException (new OperationNotSupportedException ());
   }

   /**
    * Can't create Syntax def's
    */
   protected void schema_rebind (
         String name,
         Object obj,
         Attributes attrs,
         Continuation cont)
      throws NamingException
   {
      cont.setError (this, name);
      throw cont.fillInException (new OperationNotSupportedException ());
   }

   /**
    * Can't create Syntax def's
    */
   protected DirContext schema_createSubcontext (
         String name,
         Attributes attrs,
         Continuation cont)
      throws NamingException
   {
      cont.setError (this, name);
      throw cont.fillInException (new OperationNotSupportedException ());
   }

   /* ***********************************************************************
    * Utility methods
    ************************************************************************/

   /* *
    * Returns true if the named class exists.
    * This is called by various bind/create/destroy type methods.
    */
   protected boolean exists (
         String name)
   {
      try
      {
         int cCode;
         NetIterationHandle iterationHandle = new NetIterationHandle (
                                             getService (),
                                             NetJNI.DSV_READ_SYNTAXES);
         NetBuffer syntaxNames = new NetBuffer (getService (),
                           NetJNI.DSV_READ_SYNTAXES,
                           environment.getBatchSize ());
         NetBuffer syntaxDefs = new NetBuffer (getService ());

         syntaxNames.putSyntaxName (name);

         getService ().readSyntaxes (
                        NetJNI.DS_SYNTAX_NAMES,
                        false,
                        syntaxNames.getHandle (),
                        iterationHandle,
                        syntaxDefs.getHandle ());
      }
      catch (Exception e)
      {
         return false;
      }
      return true;
   }

} /* NetSyntaxDefinitionsDirContext */


/* **************************************************************************
 * SyntaxDefinitionsNameClassEnumerator
 ***************************************************************************/

/** @internal
 * NamingEnumeration subclass setup specifically for
 * NetSyntaxDefinitionsDirContext.  This will enumerate all
 * Syntax Definitions.
 */
class SyntaxDefinitionsNameClassEnumerator implements NamingEnumeration
{
   private NetService service;
   private NetIterationHandle iterationHandle;
   private NetBuffer syntaxDefs;
   private int entriesLeft;
   private NetSyntaxDefinitionsDirContext syntaxDefsContext;
   private static NdsNamingExceptionFactory exceptionFactory =
       new NdsNamingExceptionFactory ();

   /**
    * Default Constructor.
    *
    * @param syntaxDefsContext      The NetSyntaxDefinitionsDirContext
    *                               constructing this class.
    */
   public SyntaxDefinitionsNameClassEnumerator (
         NetSyntaxDefinitionsDirContext syntaxDefsContext)
      throws NamingException
   {
      try
      {
         this.service = syntaxDefsContext.getService ();
         this.syntaxDefsContext = syntaxDefsContext;
         iterationHandle = new NetIterationHandle (
                                 service,
                                 NetJNI.DSV_READ_SYNTAXES);
         syntaxDefs = new NetBuffer (
                           service,
                           syntaxDefsContext.environment.getBatchSize ());
         getSyntaxDefs ();
      }
      catch (Exception e)
      {
         NamingException ne = new NamingException ();
         ne.setRootCause (e);
         throw ne;
      }
   }

   /**
    * Returns false only when syntaxDefs buffer is empty and there are
    * no more iterations of NWDSReadSyntaxes to perform.
    */
   public boolean hasMoreElements ()
   {
      if ((0 == entriesLeft) && (false == iterationHandle.moreIterations ()))
      {
         return false;
      }
      return true;
   }

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

   /**
    * Returns the next element in the syntaxDefs buffer.  If the buffer is
    * empty, it attempts to refill it.
    */
   public Object nextElement ()
   {
      if (false == this.hasMoreElements ())
      {
         throw (new NoSuchElementException ());
      }

      if (0 == entriesLeft)
      {
         // No more elements in this buffer, get next buffer
         getSyntaxDefs ();
      }

      StringBuffer syntaxDefName = new StringBuffer ();

      try
      {
         NetSyntaxInfo syntaxInfo = new NetSyntaxInfo ();

         // Get next element from this buffer
         syntaxDefs.getSyntaxDef (syntaxDefName, syntaxInfo);
         entriesLeft--;
      }
      catch (NSIException e)
      {
         throw (new NoSuchElementException ());
      }
      return (new NameClassPair (
                     new String (syntaxDefName),
                     Schema.SCHEMA_SYNTAX));

   } /*  */

   /**
    *
    */
   public Object next ()
   {
      return nextElement ();
   }

   /**
    * Helper method that iteratively fills the syntaxDefs buffer
    */
   private void getSyntaxDefs ()
      throws NoSuchElementException
   {
      int cCode;

      try
      {
         // Execute the NWDSReadSyntaxes native method
         service.readSyntaxes (
                     NetJNI.DS_SYNTAX_NAMES,
                     true,
                     0,
                     iterationHandle,
                     syntaxDefs.getHandle ());

         entriesLeft = syntaxDefs.getSyntaxCount ();
      }
      catch (Exception e)
      {
         throw new NoSuchElementException (e.getMessage ());
      }

   }

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

} /* SyntaxDefinitionsNameClassEnumerator */



/* **************************************************************************
 * SyntaxDefinitionsBindingEnumerator
 ***************************************************************************/

/** @internal
 * NamingEnumeration subclass setup specifically for
 * NetSyntaxDefinitionsDirContext.  This will enumerate all
 * Syntax Definitions.
 */
class SyntaxDefinitionsBindingEnumerator implements NamingEnumeration
{
   private static ContextFactory factory = new SchemaContextFactory ();
   private static NdsNamingExceptionFactory exceptionFactory =
       new NdsNamingExceptionFactory ();

   private NetService service;
   private NetIterationHandle iterationHandle;
   private NetBuffer syntaxDefs;
   private int entriesLeft;
   private NetSyntaxDefinitionsDirContext syntaxDefsContext;


   /**
    * Default Constructor.
    *
    * @param syntaxDefsContext     The NetSyntaxDefinitionsDirContext
    *                            constructing this class.
    */
   public SyntaxDefinitionsBindingEnumerator (
         NetSyntaxDefinitionsDirContext syntaxDefsContext)
      throws NamingException
   {
      try
      {
         service = syntaxDefsContext.getService ();
         this.syntaxDefsContext = syntaxDefsContext;
         iterationHandle = new NetIterationHandle (
                                 service,
                                 NetJNI.DSV_READ_SYNTAXES);
         syntaxDefs = new NetBuffer (
                        service,
                        syntaxDefsContext.environment.getBatchSize ());
         getSyntaxDefs ();
      }
      catch (Exception e)
      {
         NamingException ne = new NamingException ();
         ne.setRootCause (e);
         throw ne;
      }
   }

   /**
    * Returns false only when syntaxDefs buffer is empty and there are
    * no more iterations of NWDSReadSyntaxes to perform.
    */
   public boolean hasMoreElements ()
   {
      if ((0 == entriesLeft) && (false == iterationHandle.moreIterations ()))
      {
         return false;
      }
      return true;
   }

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

   /**
    * Returns the next element in the syntaxDefs buffer.  If the buffer is
    * empty, it attempts to refill it.
    */
   public Object nextElement ()
   {
      if (false == this.hasMoreElements ())
      {
         throw (new NoSuchElementException ());
      }

      if (0 == entriesLeft)
      {
         // No more elements in this buffer, get next buffer
         getSyntaxDefs ();
      }

      StringBuffer syntaxDefName = new StringBuffer ();
      NetSyntaxInfo syntaxInfo = new NetSyntaxInfo ();

      try
      {
         // Get next element from this buffer
         syntaxDefs.getSyntaxDef (
               syntaxDefName,
               syntaxInfo);
         entriesLeft--;
      }
      catch (NSIException e)
      {
         throw (new NoSuchElementException ());
      }

      Context ndsChildContext;

      try
      {
         ndsChildContext = factory.getContextInstance (
                     new String (
                           "\"" + syntaxDefName + "\"." +
                           syntaxDefsContext.getDistinguishedName ()),
                     syntaxDefsContext.environment);
      }
      catch (NamingException e)
      {
         throw (new NoSuchElementException (e.getMessage ()));
      }

      return (new Binding (
                     new String (syntaxDefName),
                     ndsChildContext));
   }

   /**
    *
    */
   public Object next ()
   {
      return nextElement ();
   }

   /* *
    *
    */
   private void getSyntaxDefs ()
      throws NoSuchElementException
   {
      try
      {
         // Execute the NWDSReadSyntaxes native method
         service.readSyntaxes (
                     NetJNI.DS_SYNTAX_NAMES,
                     true,
                     0,
                     iterationHandle,
                     syntaxDefs.getHandle ());

         entriesLeft = syntaxDefs.getSyntaxCount ();
      }
      catch (Exception e)
      {
         throw new NoSuchElementException (e.getMessage ());
      }

   } /* getSyntaxDefs () */

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

} /* SyntaxDefinitionsBindingEnumerator */
