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

  $Archive: /njcl_v2/src/com/novell/service/nds/naming/net/SchemaStaticDirContext.java $
  $Revision: 2 $
  $Modtime: 10/28/99 10:37a $
 
  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.novell.utility.naming.FlatNameParser;


/**@internal
 * Schema context for an abstract system (intended to be subclassed).
 *
 * <p>This is the root schema DirContext that is returned from
 * DSCotnext.getSchema methods. It can also be subclassed to provide the
 * class definitions class.
 * </p>
 *
 * <p>See com.novell.service.bindery.naming.BinderySchemaContext for an example of how
 * to subclass this class for the schema object.
 * </p>
 *
 * <p>See com.novell.service.bindery.naming.BinderySchemaClassDefsContext for an
 * example of how to subclass this class for the class definitions object.
 * </p>
 */
public class SchemaStaticDirContext implements DirContext
{
   private static NameParser flatNameParser = new FlatNameParser ();
   protected NameParser nameParser = flatNameParser;

   protected String distinguishedName;
   protected NetEnvironment environment;
   private Hashtable bindings;

   /**
    *
    */
   public SchemaStaticDirContext (
         String name,
         NamingEnumeration enumeration,
         NetEnvironment environment)
      throws NamingException
   {
      this.distinguishedName = name;
      this.environment = (NetEnvironment) environment.clone ();

      bindings = new Hashtable ();

      while (enumeration.hasMore ())
      {
         Binding binding = (Binding) enumeration.next ();

         bindings.put (binding.getName (), binding);
      }
   }


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

   /** @internal
    *
    */
   public String getNameInNamespace ()
      throws NamingException
   {
      return (distinguishedName);
   }

   /** @internal
    *
    */
   public Object lookup (
         String name)
      throws NamingException
   {  // Use the Name form of this method
      return (lookup (new CompositeName (name)));
   }

   /** @internal
    *
    */
   public Object lookup (
         Name name)
      throws NamingException
   {
      if (name == null || name.size () == 0)
      {  // The caller wants THIS context
         return (this);
      }
      else
      {  // The caller wants a subordinate context
         String target = name.get (0);
         Binding binding;

         if ((binding = (Binding) bindings.get (target)) != null)
         {
            if (name.size () > 1)
            {
               NameNotFoundException nnfe = new NameNotFoundException();
               nnfe.setResolvedName( new CompositeName(target) );
               nnfe.setRemainingName( name.getSuffix (1) );
               nnfe.setResolvedObj (binding);
               throw( nnfe );
            }
            return (binding.getObject ());
         }
         NamingException e = new NameNotFoundException ();
         e.setResolvedName (new CompositeName());
         e.setRemainingName (name);
         e.setResolvedObj (this);
         throw (e);
      }
   }

   public void bind (
         String name,
         Object obj)
      throws NamingException
   {  // The default is a non-modifiable schema so dont support this method
      throw new OperationNotSupportedException();
   }
   public void bind (
         Name name,
         Object obj)
      throws NamingException
   {  // The default is a non-modifiable schema so dont support this method
      throw new OperationNotSupportedException();
   }
   public void rebind (
         String name,
         Object obj)
      throws NamingException
   {  // The default is a non-modifiable schema so dont support this method
      throw new OperationNotSupportedException();
   }
   public void rebind (
         Name name,
         Object obj)
      throws NamingException
   {  // The default is a non-modifiable schema so dont support this method
      throw new OperationNotSupportedException();
   }
   public void unbind (
         String name)
      throws NamingException
   {  // The default is a non-modifiable schema so dont support this method
      throw new OperationNotSupportedException();
   }
   public void unbind (
         Name name)
      throws NamingException
   {  // The default is a non-modifiable schema so dont support this method
      throw new OperationNotSupportedException();
   }
   public void rename (
         String oldName,
         String newName)
      throws NamingException
   {  // The default is a non-modifiable schema so dont support this method
      throw new OperationNotSupportedException();
   }
   public void rename (
         Name oldName,
         Name newName)
      throws NamingException
   {  // The default is a non-modifiable schema so dont support this method
      throw new OperationNotSupportedException();
   }

   public NamingEnumeration list (
         String name)
      throws NamingException
   {  // Use the Name form of this method
      return (list (new CompositeName (name)));
   }

   public NamingEnumeration list (
         Name name)
      throws NamingException
   {
      if (name == null || name.size () == 0)
      {  // The caller wants the list for THIS context
         return (new NamingEnumerator ());
      }
      else
      {  // The lookup will throw an exception so we don't need to
         Object obj = lookup (name);

         if (obj instanceof Context)
            return (((Context) obj).list (""));
         else
         {
            NotContextException nce = new NotContextException();
            nce.setResolvedName( new CompositeName() );
            nce.setRemainingName( name );
            nce.setResolvedObj( obj );
            throw( nce );
         }
      }
   }

   public NamingEnumeration listBindings (
         String name)
      throws NamingException
   {  // Use the Name form of this method
      return (listBindings (new CompositeName (name)));
   }

   public NamingEnumeration listBindings (
         Name name)
      throws NamingException
   {
      if (name == null || name.size () == 0)
      {  // The caller wants the list for THIS context
         return (new NamingEnumerator ());
      }
      else
      {  // The lookup will throw an exception so we don't need to
         Object obj = lookup (name);
         if (obj instanceof Context)
            return (((Context) obj).listBindings (""));
         else
         {
            NotContextException nce = new NotContextException();
            nce.setResolvedName( new CompositeName() );
            nce.setRemainingName( name );
            nce.setResolvedObj( obj );
            throw( nce );
         }
      }
   }

   public void destroySubcontext (
         String name)
      throws NamingException
   {  // The default is a non-modifiable schema so dont support this method
      throw new OperationNotSupportedException();
   }
   public void destroySubcontext (
         Name name)
      throws NamingException
   {  // The default is a non-modifiable schema so dont support this method
      throw new OperationNotSupportedException();
   }
   public Context createSubcontext (
         String name)
      throws NamingException
   {  // The default is a non-modifiable schema so dont support this method
      throw new OperationNotSupportedException();
   }
   public Context createSubcontext (
         Name name)
      throws NamingException
   {  // The default is a non-modifiable schema so dont support this method
      throw new OperationNotSupportedException();
   }
   public Object lookupLink (
         String name)
      throws NamingException
   {  // Use the Name form of this method
      return (lookupLink (new CompositeName (name)));
   }
   public Object lookupLink (
         Name name)
      throws NamingException
   {  // We just use lookup for lookupLink
      return (lookup (name));
   }
   public NameParser getNameParser (
         String name)
      throws NamingException
   {  // Use the Name form of this method
      return (getNameParser (new CompositeName (name)));
   }
   public NameParser getNameParser (
         Name name)
      throws NamingException
   {
      if (name == null || name.size () == 0)
      {  // The caller wants the list for THIS context
         return (nameParser);
      }
      else
      {  // The lookup will throw an exception so we don't need to
         Object obj = lookup (name);
         if (obj instanceof Context)
            return (((Context) obj).getNameParser (""));
         else
         {
            NotContextException nce = new NotContextException();
            nce.setResolvedName( new CompositeName() );
            nce.setRemainingName( name );
            nce.setResolvedObj( obj );
            throw( nce );
         }
      }
   }

   public Object addToEnvironment (
         String key,
         Object value ) 
      throws NamingException
   {
      return (environment.addToEnvironment (key, value));
   }

   public Hashtable getEnvironment ()
      throws NamingException
   {
      return (environment.getEnvironment ());
   }

   public Object removeFromEnvironment (
         String key) 
      throws NamingException
   {
      return (environment.removeFromEnvironment (key));
   }

   public String composeName (
         String name, 
         String prefix)
      throws NamingException 
   {
      throw new OperationNotSupportedException();
   }

   public Name composeName (
         Name name, 
         Name prefix)
      throws NamingException 
   {
      throw new OperationNotSupportedException();
   }

   public void close ()
      throws NamingException
   {
      //... no close necessary
   }

   /* ***********************************************************************
    * DirContext Methods
    ************************************************************************/
   public Attributes getAttributes (
         String name)
      throws NamingException
   {  // Use the Name form of this method
      return (getAttributes (new CompositeName (name)));
   }
   public Attributes getAttributes (
         Name name)
      throws NamingException
   {  // Use the attribute id form of this method
      return (getAttributes (name, (String[]) null));
   }
   public Attributes getAttributes (
         String name,
         String[] attrIds)
      throws NamingException
   {  // Use the Name form of this method
      return (getAttributes (new CompositeName (name), attrIds));
   }
   /**
    * This is the only getAttribute method a subclass must override
    */
   public Attributes getAttributes (
         Name name,
         String[] attrIds)
      throws NamingException
   {  // No default support for meta-data on the schema
      throw new OperationNotSupportedException();
   }
   public void modifyAttributes (
         String name,
         int mod_op,
         Attributes attrs)
      throws NamingException
   {
      throw new OperationNotSupportedException();
   }
   public void modifyAttributes (
         Name name,
         int mod_op,
         Attributes attrs)
      throws NamingException
   {  // The default is a non-modifiable schema so dont support this method
      throw new OperationNotSupportedException();
   }
   public void modifyAttributes (
         String name,
         ModificationItem[] mods)
      throws NamingException
   {  // The default is a non-modifiable schema so dont support this method
      throw new OperationNotSupportedException();
   }
   public void modifyAttributes (
         Name name,
         ModificationItem[] mods)
      throws NamingException
   {  // The default is a non-modifiable schema so dont support this method
      throw new OperationNotSupportedException();
   }
   public void bind (
         String name,
         Object obj,
         Attributes attrs)
      throws NamingException
   {  // The default is a non-modifiable schema so dont support this method
      throw new OperationNotSupportedException();
   }
   public void bind (
         Name name,
         Object obj,
         Attributes attrs)
      throws NamingException
   {  // The default is a non-modifiable schema so dont support this method
      throw new OperationNotSupportedException();
   }
   public void rebind (
         String name,
         Object obj,
         Attributes attrs)
      throws NamingException
   {  // The default is a non-modifiable schema so dont support this method
      throw new OperationNotSupportedException();
   }
   public void rebind (
         Name name,
         Object obj,
         Attributes attrs)
      throws NamingException
   {  // The default is a non-modifiable schema so dont support this method
      throw new OperationNotSupportedException();
   }
   public DirContext createSubcontext (
         String name, 
         Attributes attrs)
      throws NamingException
   {  // The default is a non-modifiable schema so dont support this method
      throw new OperationNotSupportedException();
   }
   public DirContext createSubcontext (
         Name name, 
         Attributes attrs)
      throws NamingException
   {  // The default is a non-modifiable schema so dont support this method
      throw new OperationNotSupportedException();
   }
   public DirContext getSchema (
         String name)
      throws NamingException
   {  // No default support for meta-data on the schema
      throw new OperationNotSupportedException();
   }
   public DirContext getSchema (
         Name name)
      throws NamingException
   {  // No default support for meta-data on the schema
      throw new OperationNotSupportedException();
   }
   public DirContext getSchemaClassDefinition (
         String name)
      throws NamingException
   {  // No default support for meta-data on the schema
      throw new OperationNotSupportedException();
   }
   public DirContext getSchemaClassDefinition (
         Name name)
      throws NamingException
   {  // No default support for meta-data on the schema
      throw new OperationNotSupportedException();
   }
   /* *************** searches *************** */
   public NamingEnumeration search (
         String name,
         Attributes matchingAttributes)
      throws NamingException
   {  // We're not supporting searching the schema
      throw new OperationNotSupportedException();
   }
   public NamingEnumeration search (
         Name name,
         Attributes matchingAttributes)
      throws NamingException
   {  // We're not supporting searching the schema
      throw new OperationNotSupportedException();
   }
   public NamingEnumeration search (
         String name, 
         Attributes matchingAttributes,
         String[] attributesToReturn)
      throws NamingException
   {  // We're not supporting searching the schema
      throw new OperationNotSupportedException();
   }
   public NamingEnumeration search (
         Name name, 
         Attributes matchingAttributes,
         String[] attributesToReturn)
      throws NamingException
   {  // We're not supporting searching the schema
      throw new OperationNotSupportedException();
   }
   public NamingEnumeration search (
         String name, 
         String filter,
         SearchControls cons)
      throws NamingException
   {  // We're not supporting searching the schema
      throw new OperationNotSupportedException();
   }
   public NamingEnumeration search (
         Name name, 
         String filter,
         SearchControls cons)
      throws NamingException
   {  // We're not supporting searching the schema
      throw new OperationNotSupportedException();
   }
   public NamingEnumeration search (
         String name,
         String filterExpr,
         Object[] filterArgs,
         SearchControls cons)
      throws NamingException
   {  // We're not supporting searching the schema
      throw new OperationNotSupportedException();
   }
   public NamingEnumeration search (
         Name name,
         String filterExpr,
         Object[] filterArgs,
         SearchControls cons)
      throws NamingException
   {  // We're not supporting searching the schema
      throw new OperationNotSupportedException();
   }


   /**
    *
    */
   class NamingEnumerator implements NamingEnumeration
   {
      private Enumeration enumeration;

      public NamingEnumerator ()
      {
         enumeration = bindings.elements ();
      }

      public boolean hasMoreElements ()
      {
         return (enumeration.hasMoreElements ());
      }

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

      public Object nextElement ()
      {
         return (enumeration.nextElement ());
      }

      public Object next ()
         throws NamingException
      {
         return (enumeration.nextElement ());
      }

      public void close ()
         throws NamingException
      {
         enumeration = null;
      }

   } /* NamingEnumerator */

} /* SchemaStaticDirContext */


