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

  $Archive: /njcl_v2/src/com/novell/service/file/nw/naming/FileSystemInitialContextFactory.java $
  $Revision: 11 $
  $Modtime: 8/23/99 5:58p $
 
  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.file.nw.naming;

import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.spi.InitialContextFactory;
import javax.naming.spi.NamingManager;
import javax.naming.NoInitialContextException;

import com.novell.service.file.nw.naming.ReferenceFactoryImpl;
import com.novell.utility.naming.spi.ReferenceFactory;
import com.novell.utility.naming.URLParser;
import com.novell.utility.naming.Environment;

/** @internal
 * Allows javax.naming.InitialContext to start name resolution in the
 * NetWare file name space.
 *
 * @see javax.naming.InitialContext
 */
public class FileSystemInitialContextFactory implements InitialContextFactory
{
   /**
    * Gets a context in the file system name space.
    *
    * <p>The context that is returned is used by the InitialContext class
    * to allow name resolution to start in the file name space.  If the
    * name specified in the FSEnvironment.PATH property federates
    * out of the file system naming system, then resolution is followed
    * outside of the file system naming system.
    *
    * <p>The environment properties are expected in this format:
    * <ul>
    * <li>FSEnvironment.SERVER_NAME = server name
    * <li>(optional) if FSEnvironment.SERVER_NAME is not present,
    *     then the property "java.naming.provider.url" will be used to
    *     supply a default value.
    * <li>FSEnvironment.PATH = full JNDI path of file system
    *     object
    * </ul>
    *
    * @param      environment    The properties defining the context
    *                            to return.
    * @return                    A fully constructed Context.
    */


   public Context getInitialContext (Hashtable environment)
      throws NamingException
   {

      String serverName = null;
      String path = null;

      // look for host and path in "java.naming.provider.url"
      URLParser urlp = new 
         URLParser((String)environment.get(Context.PROVIDER_URL));
      serverName = urlp.getHost();
      path = urlp.getPath();

      if (serverName == null)
         throw new NoInitialContextException();

      if (path == null)
         path = "";

      try
      {
         FileSystemInitialDirContext ctx = new 
            FileSystemInitialDirContext(serverName, environment);
         return ((Context)ctx.lookup(path));
      } catch (Exception e)
      {
         NamingException ne = new NoInitialContextException();

         ne.setRootCause(e);

         throw ne;
      }
   }

/* 
   the following was the original getInitialContext method to illiminate
   the double tap on the FileSystemInitialDirContext, the above method was
   adopted.
*/
   public Context originalGetInitialContext (Hashtable environment)
      throws NamingException
   {
      ReferenceFactory refFact = new ReferenceFactoryImpl ();
/*
   The following line causes a FileSystemInitialDirContext to be created, see 
   ReferenceFactoryImpl line 92
   ReferenceFactoryImpl line 120 
   ContextFactoryImpl line   154

   The NamingManager.getObjectInstance, then obtains another 
   FileSystemInitialDirContext, see
   ContextFactoryImpl line 108
   ContextFactoryImpl line 154

can this be optimized?
*/
      Reference ref = refFact.createReference (environment);
      Context ctx;

      try
      {
         ctx = (Context) NamingManager.getObjectInstance (ref, 
            null, null, environment);
      }
      catch (ClassCastException ce)
      {
         throw new NoInitialContextException();
//         return (null);
      }
      catch (Exception e)
      {
         throw new NoInitialContextException();
//         return (null);
      }

      if (ctx == null)
         throw new NoInitialContextException();

      return (ctx);
   }
}
