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

  $Archive: /njcl_v2/src/com/novell/service/nds/naming/local/NdsDirContext.java $
  $Revision: 18 $
  $Modtime: 1/28/00 12:45p $
 
  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.local;


import java.io.Serializable;

import java.util.Date;
import java.util.NoSuchElementException;

import javax.naming.Context;
import javax.naming.Name;
import javax.naming.CompositeName;
import javax.naming.Binding;
import javax.naming.Reference;
import javax.naming.Referenceable;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.directory.Attributes;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;

import com.novell.service.jncp.NSIException;

import com.novell.service.nds.NdsObject;
import com.novell.service.nds.NdsObjectRights;
import com.novell.service.nds.NdsAttributeRights;
import com.novell.service.nds.NdsIterator;
import com.novell.service.nds.NdsIteratorControls;
import com.novell.service.nds.NdsIteratorFactory;
import com.novell.service.nds.naming.NdsNameClassPair;
import com.novell.service.nds.naming.NdsEnvironment;
import com.novell.service.nds.naming.NdsDirContextWrappable;
import com.novell.service.nds.naming.SchemaDirContextWrappable;
import com.novell.service.nds.naming.PartitionDirContextWrappable;
import com.novell.service.nds.naming.NdsNamingEnumeratorWrappable;
import com.novell.service.nds.naming.Partitionable;

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


/** @internal
 *
 */
public class NdsDirContext
   extends DirContextWrapper
   implements NdsObject, Serializable
{
   protected static ContextFactory factory;
   protected static ContextFactory schemaFactory;
   protected static ContextFactory partitionFactory;

   static
   {
      factory = new NdsContextFactory ();
      schemaFactory = new SchemaContextFactory ();
      partitionFactory = new PartitionContextFactory ();

   } /* static */

   protected NdsEnvironment environment;


   /**
    *
    */
   protected NdsDirContext (
         NdsDirContextWrappable impl,
         NdsEnvironment environment)
      throws NamingException
   {
      super (impl);

      this.environment = environment;

   } /* NdsDirContext () */


   // ******************** Context Interface ********************

   /**
    *
    */
   public Object lookup (
         Name name)
      throws NamingException
   {
      Object object = ((Context) impl).lookup (name);

      if (object instanceof NdsDirContextWrappable)
      {
         return (factory.getContextInstance ((Context) object));
      }
      return (object);

   } /* lookup () */

   /**
    *
    */
   public NamingEnumeration list (
         Name name)
      throws NamingException
   {
      NamingEnumeration namingEnumeration = ((Context) impl).list (name);

      if (namingEnumeration instanceof NdsNamingEnumeratorWrappable)
      {
         return (new NdsNameClassEnumerator (namingEnumeration));
      }
      return (namingEnumeration);

   } /* list () */

   /**
    *
    */
   public NamingEnumeration listBindings (
         Name name)
      throws NamingException
   {
      NamingEnumeration namingEnumeration;

      namingEnumeration = ((Context) impl).listBindings (name);
      if (namingEnumeration instanceof NdsNamingEnumeratorWrappable)
      {
         return (new NdsBindingEnumerator (namingEnumeration, environment));
      }
      return (namingEnumeration);

   } /* listBindings () */

   /**
    *
    */
   public Context createSubcontext (
         Name name)
      throws NamingException
   {
      Context context = ((Context) impl).createSubcontext (name);

      if (context instanceof NdsDirContextWrappable)
      {
         return (factory.getContextInstance (context));
      }
      return (context);

   } /* createSubcontext () */

   /**
    *
    */
   public Object lookupLink (
         Name name)
      throws NamingException
   {
      Object object = ((Context) impl).lookupLink (name);

      if (object instanceof NdsDirContextWrappable)
      {
         return (factory.getContextInstance ((Context) object));
      }
      return (object);

   } /* lookupLink () */


   // ******************** DirContext Interface ********************

   /**
    *
    */
   public DirContext createSubcontext (
         Name name,
         Attributes attrs)
      throws NamingException
   {
      DirContext context;

      context = ((DirContext) impl).createSubcontext (name, attrs);

      if (context instanceof NdsDirContextWrappable)
      {
         return ((DirContext) factory.getContextInstance (context));
      }
      return (context);

   } /* createSubcontext () */

   /**
    *
    */
   public DirContext getSchema (
         Name name)
      throws NamingException
   {
      DirContext context;

      context = ((DirContext) impl).getSchema (name);

      if (context instanceof SchemaDirContextWrappable)
      {
         return ((DirContext) schemaFactory.getContextInstance (context));
      }
      return (context);

   } /* getSchema () */

   /**
    *
    */
   public DirContext getSchemaClassDefinition (
         Name name)
      throws NamingException
   {
      DirContext context;

      context = ((DirContext) impl).getSchemaClassDefinition (name);

      if (context instanceof SchemaDirContextWrappable)
      {
         return ((DirContext) schemaFactory.getContextInstance (context));
      }
      return (context);

   } /* getSchemaClassDefinition () */

   /**
    *
    */
   public NamingEnumeration search (
         Name name,
         Attributes matchingAttributes,
         String[] attributesToReturn)
      throws NamingException
   {
      NamingEnumeration namingEnumeration;

      namingEnumeration = ((DirContext) impl).search (
                                          name,
                                          matchingAttributes,
                                          attributesToReturn);

      if (namingEnumeration instanceof NdsNamingEnumeratorWrappable)
      {
         return (new NdsSearchEnumerator (namingEnumeration, environment));
      }
      return (namingEnumeration);

   } /* search () */

   /**
    *
    */
   public NamingEnumeration search (
         Name name,
         String filter,
         SearchControls cons)
      throws NamingException
   {
      NamingEnumeration namingEnumeration;

      namingEnumeration = ((DirContext) impl).search (name, filter, cons);
      if (namingEnumeration instanceof NdsNamingEnumeratorWrappable)
      {
         return (new NdsSearchEnumerator (namingEnumeration, environment));
      }
      return (namingEnumeration);

   } /* search () */

   /**
    *
    */
   public NamingEnumeration search (
         Name name,
         String filterExpr,
         Object [] filterArgs,
         SearchControls cons)
      throws NamingException
   {
      NamingEnumeration namingEnumeration;

      namingEnumeration = ((DirContext) impl).search (
                                       name,
                                       filterExpr,
                                       filterArgs,
                                       cons);
      if (namingEnumeration instanceof NdsNamingEnumeratorWrappable)
      {
         return (new NdsSearchEnumerator (namingEnumeration, environment));
      }
      return (namingEnumeration);

   } /* search () */


   // ******************** NdsObject Interface ********************

   /**
    *
    */
   public String getDistinguishedName ()
   {
      return (((NdsObject) impl).getDistinguishedName ());
   }

   /**
    *
    */
   public int getObjectFlags ()
      throws NSIException
   {
      return (((NdsObject) impl).getObjectFlags ());
   }

   /**
    *
    */
   public int getSubordinateCount ()
      throws NSIException
   {
      return (((NdsObject) impl).getSubordinateCount ());
   }

   /**
    *
    */
   public Date getModificationTime ()
      throws NSIException
   {
      return (((NdsObject) impl).getModificationTime ());
   }

   /**
    *
    */
   public String getBaseClass ()
      throws NSIException
   {
      return (((NdsObject) impl).getBaseClass ());
   }

   /**
    *
    */
   public String getTreeName ()
   {
      return (((NdsObject) impl).getTreeName ());
   }

   /**
    *
    */
   public NdsObjectRights getObjectEffectiveRights (
         NdsObject trustee)
      throws NSIException
   {
      return (((NdsObject) impl).getObjectEffectiveRights (trustee));
   }

   /**
    *
    */
   public NdsObjectRights getObjectEffectiveRights (
         String trustee)
      throws NSIException
   {
      return (((NdsObject) impl).getObjectEffectiveRights (trustee));
   }


   /**
    *
    */
   public NdsAttributeRights getAttributeEffectiveRights (
         NdsObject trustee)
      throws NSIException
   {
      return (((NdsObject) impl).getAttributeEffectiveRights (trustee));
   }

   /**
    *
    */
   public NdsAttributeRights getAttributeEffectiveRights (
         String trustee)
      throws NSIException
   {
      return (((NdsObject) impl).getAttributeEffectiveRights (trustee));
   }


   /**
    *
    */
   public NdsAttributeRights getAttributeEffectiveRights (
         NdsObject trustee,
         String attrName)
      throws NSIException
   {
      return (((NdsObject) impl).getAttributeEffectiveRights (
                                    trustee,
                                    attrName));
   }

   /**
    *
    */
   public NdsAttributeRights getAttributeEffectiveRights (
         String trustee,
         String attrName)
      throws NSIException
   {
      return (((NdsObject) impl).getAttributeEffectiveRights (
                                    trustee,
                                    attrName));
   }
   
   /**
    *
    */
   public NamingEnumeration getAttributesEffectiveRights (
         NdsObject trustee,
         String[] attrIds)
      throws NSIException
   {
      return (((NdsObject) impl).getAttributesEffectiveRights (
                                    trustee,
                                    attrIds));
   }

   /**
    *
    */
   public NamingEnumeration getAttributesEffectiveRights (
         String trustee,
         String[] attrIds)
      throws NSIException
   {
      return (((NdsObject) impl).getAttributesEffectiveRights (
                                    trustee,
                                    attrIds));
   }

   /**
    *
    */
   public NamingEnumeration list (
         String name,
         boolean containers)
      throws NamingException
   {
      NamingEnumeration namingEnumeration = ((NdsObject) impl).list (
                                                            name,
                                                            containers);

      if (namingEnumeration instanceof NdsNamingEnumeratorWrappable)
      {
         return (new NdsFilteredNameClassEnumerator (namingEnumeration));
      }
      return (namingEnumeration);

   } /* list () */

   /**
    *
    */
   public NamingEnumeration list (
         String name,
         String className,
         String subordinateName)
      throws NamingException
   {
      NamingEnumeration namingEnumeration = ((NdsObject) impl).list (
                                                            name,
                                                            className,
                                                            subordinateName);

      if (namingEnumeration instanceof NdsNamingEnumeratorWrappable)
      {
         return (new NdsFilteredNameClassEnumerator (namingEnumeration));
      }
      return (namingEnumeration);

   } /* list () */

   /**
    *
    */
   public NamingEnumeration listBindings (
      String name,
      boolean containers)
      throws NamingException
   {
      NamingEnumeration namingEnumeration;

      namingEnumeration = ((NdsObject) impl).listBindings (
                                                name,
                                                containers);

      if (namingEnumeration instanceof NdsNamingEnumeratorWrappable)
      {
         return (new NdsFilteredBindingEnumerator (namingEnumeration));
      }
      return (namingEnumeration);

   } /* listBindings () */

   /**
    *
    */
   public NamingEnumeration listBindings (
      String name,
      String className,
      String subordinateName)
      throws NamingException
   {
      NamingEnumeration namingEnumeration;

      namingEnumeration = ((NdsObject) impl).listBindings (
                                                name,
                                                className,
                                                subordinateName);

      if (namingEnumeration instanceof NdsNamingEnumeratorWrappable)
      {
         return (new NdsFilteredBindingEnumerator (namingEnumeration));
      }
      return (namingEnumeration);

   } /* listBindings () */

   // ******************** NdsIteratorFactory Interface ********************

   /**
    *
    */
   public NdsIterator createIterator (
         String name, 
         Attributes matchingAttributes,
         String[] attributesToReturn)
      throws NSIException
   {
      return (((NdsIteratorFactory) impl).createIterator (
                                                   name, 
                                                   matchingAttributes,
                                                   attributesToReturn));
   }

   /**
    *
    */
   public NdsIterator createIterator (
         String name, 
         Attributes matchingAttributes)
      throws NSIException
   {
      return (((NdsIteratorFactory) impl).createIterator (
                                                   name,
                                                   matchingAttributes));
   }

   /**
    *
    */
   public NdsIterator createIterator (
         String name, 
         String filter,
         NdsIteratorControls cons)
      throws NSIException
   {
      return (((NdsIteratorFactory) impl).createIterator (
                                                   name, 
                                                   filter,
                                                   cons));
   }

   /**
    *
    */
   public NdsIterator createIterator (
         String name, 
         String filterExpr,
         Object[] filterArgs,
         NdsIteratorControls cons)
      throws NSIException
   {
      return (((NdsIteratorFactory) impl).createIterator (
                                                   name,
                                                   filterExpr,
                                                   filterArgs,
                                                   cons));
   }

   /**
    *
    */
   public NdsIterator createIterator (
         String name,
         NdsIteratorControls cons,
         String className,
         String subordinateName)
      throws NSIException
   {
      return (((NdsIteratorFactory) impl).createIterator (
                                                   name,
                                                   cons,
                                                   className,
                                                   subordinateName));
   }

   // ******************** Referenceable Interface ********************

   /**
    * Retrieves the Reference of this object.
    *
    * @return the Reference of this object.
    */
   public Reference getReference ()
      throws NamingException
   {
      return (((Referenceable) impl).getReference ());

   } /* getReference () */


   // ******************** Partitionable Interface ********************

   /**
    *
    */
   public Context getPartitionRoot (
         String name)
      throws NamingException
   {
      Context context;

      context = ((Partitionable) impl).getPartitionRoot (name);

      if (context instanceof PartitionDirContextWrappable)
      {
         return ((Context) partitionFactory.getContextInstance (context));
      }
      return (context);

   } /* getPartitionRoot () */

   /**
    *
    */
   public Context getPartitionRoot (
         Name name)
      throws NamingException
   {
      Context context;

      context = ((Partitionable) impl).getPartitionRoot (name);

      if (context instanceof PartitionDirContextWrappable)
      {
         return ((Context) partitionFactory.getContextInstance (context));
      }
      return (context);

   } /* getPartitionRoot () */

   /**
    *
    */
   public DirContext getPartition (
         String name)
      throws NamingException
   {
      DirContext context;

      context = ((Partitionable) impl).getPartition (name);

      if (context instanceof PartitionDirContextWrappable)
      {
         return ((DirContext) partitionFactory.getContextInstance (context));
      }
      return (context);

   } /* getPartition () */

   /**
    *
    */
   public DirContext getPartition (
         Name name)
      throws NamingException
   {
      DirContext context;

      context = ((Partitionable) impl).getPartition (name);

      if (context instanceof PartitionDirContextWrappable)
      {
         return ((DirContext) partitionFactory.getContextInstance (context));
      }
      return (context);

   } /* getPartition () */

} /* NdsDirContext */


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

/** @internal
 *
 */
class NdsNameClassEnumerator implements NamingEnumeration
{
   protected static NdsContextFactory factory = new NdsContextFactory ();

   private NamingEnumeration impl;

   /**
    *
    */
   protected NdsNameClassEnumerator (NamingEnumeration impl)
   {
      this.impl = impl;
   }

   /**
    *
    */
   public boolean hasMoreElements ()
   {
      return (impl.hasMoreElements ());
   }

   /**
    *
    */
   public boolean hasMore ()
      throws NamingException
   {
      return (impl.hasMore ());
   }

   /**
    *
    */
   public Object nextElement ()
   {
      try
      {
         return (next ());
      }
      catch (NamingException e)
      {
         throw (new NoSuchElementException ());
      }

   }

   /**
    *
    */
   public Object next ()
      throws NamingException
   {
      NdsNameClassPair pair = (NdsNameClassPair) impl.next ();

      pair.setClassName (factory.getClassName (pair.getBaseClass ()));
      return (pair);
   }

   /**
    *
    */
   public void close ()
      throws NamingException
   {
   }

} /* NdsNameClassEnumerator */


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

/** @internal
 *
 */
class NdsFilteredNameClassEnumerator implements NamingEnumeration
{
   protected static NdsContextFactory factory = new NdsContextFactory ();

   private NamingEnumeration impl;

   /**
    *
    */
   protected NdsFilteredNameClassEnumerator (NamingEnumeration impl)
   {
      this.impl = impl;
   }

   /**
    *
    */
   public boolean hasMoreElements ()
   {
      return (impl.hasMoreElements ());
   }

   /**
    *
    */
   public boolean hasMore ()
      throws NamingException
   {
      return (impl.hasMore ());
   }

   /**
    *
    */
   public Object nextElement ()
   {
      try
      {
         return (next ());
      }
      catch (NamingException e)
      {
         throw (new NoSuchElementException ());
      }

   }

   /**
    *
    */
   public Object next ()
      throws NamingException
   {
      NdsNameClassPair pair = (NdsNameClassPair) impl.next ();

      pair.setClassName (factory.getClassName (pair.getBaseClass ()));
      return (pair);
   }

   /**
    *
    */
   public void close ()
      throws NamingException
   {
   }

} /* NdsFilteredNameClassEnumerator */


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

/** @internal
 *
 */
class NdsBindingEnumerator implements NamingEnumeration
{
   protected static NdsContextFactory factory = new NdsContextFactory ();

   private NamingEnumeration impl;
   private NdsEnvironment environment;

   /**
    *
    */
   protected NdsBindingEnumerator (
         NamingEnumeration impl,
         NdsEnvironment environment)
   {
      this.impl = impl;
      this.environment = environment;
   }

   /**
    *
    */
   public boolean hasMoreElements ()
   {
      return (impl.hasMoreElements ());
   }

   /**
    *
    */
   public boolean hasMore ()
      throws NamingException
   {
      return (impl.hasMore ());
   }

   /**
    *
    */
   public Object nextElement ()
   {
      try
      {
         return (next ());
      }
      catch (NamingException e)
      {
         throw (new NoSuchElementException ());
      }

   }

   /**
    *
    */
   public Object next ()
      throws NamingException
   {
      Binding binding = (Binding) impl.next ();

      binding.setObject (
                  factory.getContextInstance (
                              (Context) binding.getObject ()));
      return (binding);

   }

   /**
    *
    */
   public void close ()
      throws NamingException
   {
   }

} /* NdsBindingEnumerator */

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

/** @internal
 *
 */
class NdsFilteredBindingEnumerator implements NamingEnumeration
{
   protected static NdsContextFactory factory = new NdsContextFactory ();

   private NamingEnumeration impl;
   private NdsEnvironment environment;

   /**
    *
    */
   protected NdsFilteredBindingEnumerator (
         NamingEnumeration impl)
   {
      this.impl = impl;
   }

   /**
    *
    */
   public boolean hasMoreElements ()
   {
      return (impl.hasMoreElements ());
   }

   /**
    *
    */
   public boolean hasMore ()
      throws NamingException
   {
      return (impl.hasMore ());
   }

   /**
    *
    */
   public Object nextElement ()
   {
      try
      {
         return (next ());
      }
      catch (NamingException e)
      {
         throw (new NoSuchElementException ());
      }

   }

   /**
    *
    */
   public Object next ()
      throws NamingException
   {
      Binding binding = (Binding) impl.next ();

      binding.setObject (
                  factory.getContextInstance (
                              (Context) binding.getObject ()));
      return (binding);

   }

   /**
    *
    */
   public void close ()
      throws NamingException
   {
   }

} /* NdsFilteredBindingEnumerator */

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

/** @internal
 *
 */
class NdsSearchEnumerator implements NamingEnumeration
{
   protected static NdsContextFactory factory = new NdsContextFactory ();

   private NamingEnumeration impl;
   private NdsEnvironment environment;

   /**
    *
    */
   protected NdsSearchEnumerator (
         NamingEnumeration impl,
         NdsEnvironment environment)
   {
      this.impl = impl;
      this.environment = environment;
   }

   /**
    *
    */
   public boolean hasMoreElements ()
   {
      return (impl.hasMoreElements ());
   }

   /**
    *
    */
   public boolean hasMore ()
      throws NamingException
   {
      return (impl.hasMore ());
   }

   /**
    *
    */
   public Object nextElement ()
   {
      try
      {
         return (next ());
      }
      catch (NamingException e)
      {
         throw (new NoSuchElementException ());
      }

   }

   /**
    *
    */
   public Object next ()
      throws NamingException
   {
      SearchResult searchResult = (SearchResult) impl.next ();

      // always set the className
      searchResult.setClassName (
                  factory.getClassName (
                              searchResult.getClassName ())); // baseClass

      // wrap the object if there is one
      if (searchResult.getObject () != null)
      {
         searchResult.setObject (
                     factory.getContextInstance (
                                 (Context) searchResult.getObject ()));
      }
      return (searchResult);

   }

   /**
    *
    */
   public void close ()
      throws NamingException
   {
   }

} /* NdsSearchEnumerator */


