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

  $Archive: /njcl_v2rmi/src/com/novell/service/session/spi/SessionManagerServiceImpl.java $
  $Revision: 22 $
  $Modtime: 1/12/01 11:57a $

  Copyright (c) 1997 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.session.spi;

import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.registry.*;
import java.util.Hashtable;
import com.novell.service.session.*;
import com.novell.service.session.util.*;

/** @internal
 * Server-side class handles creating new session managers
 */
public class SessionManagerServiceImpl extends UnicastRemoteObject
implements SessionManagerService
{
   // Always access debug via final static...hopefully a final static of
   // false will be optimized out by the compiler
	final static private boolean DEBUG = false;
	final static private boolean S_DEBUG = false; // May have side effects

   static SessionManagerService singletonInstance = null;
   private static boolean forcePrivate = false;

   protected SessionManagerServiceImpl() throws SessionException, RemoteException
   {
      TestBuildMarker.emit();
   }

   static public SessionManagerService getInstance()
   throws SessionException, RemoteException
   {
      if (null == singletonInstance)
         singletonInstance = new SessionManagerServiceImpl();
      return singletonInstance;
   }

   /**
    * Inherited from SessionManagerService.
    */
   public SessionManager getSessionManager
   (
      SessionEnv environment,
      int scope
   )
   throws SessionException, RemoteException
   {
      if (DEBUG)
      {
	      Debug.println("->SMSI.getSessionManager()");
      }
      //the scope check must occur here on the remote side.
      if(System.getProperty("os.name").startsWith("NetWare"))
         scope |= SessionManagerFactory.NO_SCAN_SCOPE;
      // NOTE: only allowing private when running from remote. Otherwise a third party could piggyback on a SessionManager
      if(forcePrivate)
         if (0 == (scope & SessionManagerFactory.PRIVATE_SCOPE))
            throw new SessionException(
               "Only PRIVATE SessionManager's allowed from remote");
      
      SessionManager sm;
      if(environment.containsKey(SessionEnv.RMI_SOCKET_FACTORIES_OBJECT))
      {
         RMISocketFactories x = (RMISocketFactories)
            environment.get(SessionEnv.RMI_SOCKET_FACTORIES_OBJECT);
         sm = new SessionManagerImpl(SessionManager.SESSION_MANAGER,
            scope, (SessionEnv)environment.clone(), x);
      }
      else
         sm = new SessionManagerImpl(SessionManager.SESSION_MANAGER,
            scope, (SessionEnv)environment.clone());

      SessionState state = new SessionManagerState(sm);

      sm.validateLinks();

      // This will spawn a daemon thread if ALLOW_BACKGROUND_VALIDATION
      // is true in environment
      spawnDaemon(sm, (SessionEnv)environment.clone());

      if (DEBUG)
      {
         Debug.println("--SMSI.getSessionManager(): ..spawn second daemon");
         spawnDaemon(
            sm,
            (SessionEnv)environment.clone());
      }
      if (DEBUG)
      {
	      Debug.println("<-SMSI.getSessionManager()");
      }
      return sm;
   }

   /*
    * Checks environment and spawns daemon thread if
    * ALLOW_BACKGROUND_VALIDATION is true
    */
   private void spawnDaemon
   (
      SessionManager sm,
      SessionEnv environment
   )
   throws SessionException
   {
      boolean runDaemon = false;
      if (DEBUG)
      {
	      Debug.println("->SMSI.spawnDaemon()");
      }
      try
      {
         Boolean runDaemonObject =
            (Boolean)environment.get(SessionEnv.ALLOW_BACKGROUND_VALIDATION);
         if (null != runDaemonObject)
         {
            runDaemon = runDaemonObject.booleanValue();
         }
         else
         {
            if (DEBUG)
            {
	            Debug.println("--SMSI.spawnDaemon(): Run daemon: env not set");
            }
         }
         if (DEBUG)
         {
	         Debug.println("--SMSI.spawnDaemon(): Run daemon: " + runDaemon);
         }

         if (runDaemon)
         {
            SessionManagerServiceDaemon sd = new SessionManagerServiceDaemon(sm);
            Thread t = new Thread(sd);

            // Dies when program ends
            t.setDaemon(true);

            // Slightly lower priority that spawning thread
            int priority = t.getPriority();
            if (priority > Thread.MIN_PRIORITY)
               priority -= 1;
            t.setPriority(priority);
            t.setName(
               sd.toString());

            // Do it
            if (DEBUG)
            {
	            Debug.println(
                  "--SMSI.spawnDaemon(): Started daemon thread: " + t.getName());
            }
            t.start();
         }
      }
      catch (Exception e)
      {
         throw new SessionException("Unexpected exception", e);
      }
      if (DEBUG)
      {
	      Debug.println("<-SMSI.spawnDaemon()");
      }
   }

   /**
    * Returns SessionManager unique to calling workstation.
    */
   public SessionManager getWorkstationSessionManager
   (
      SessionEnv environment,
      int scope
   )
   throws SessionException, RemoteException
   {
      throw new SessionException("NOT IMPLEMENTED");
/*
      String workstation;
      try
      {
         workstation = this.getClientHost();
      }
      catch (java.rmi.server.ServerNotActiveException e)
      {
//       Misc.consoleException(e);
         throw new SessionException("Unexpected exception", e);
      }
      SessionManager sm;
      if (workstationSessionManagers.containsKey(workstation))
         sm = (SessionManager)workstationSessionManagers.get(workstation);
      else
      {
         sm = getSessionManager((SessionEnv)environment.clone());
         workstationSessionManagers.put(workstation, sm);
      }
      return sm;
*/
   }

   public static void main(String argv[])
   {
      try
      {
         if(System.getSecurityManager() == null)
         {
            System.out.println("Load RMISecurityManager");
            System.setSecurityManager(new RMISecurityManager());
         }
         Registry reg = LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
         SessionManagerService sms = SessionManagerServiceImpl.getInstance();
         forcePrivate = true;
         reg.rebind(SessionEnv.SESSION_MANAGER_URL, sms);
         if(DEBUG)
         {
            System.out.println("Registry: " + reg.toString());
            System.out.println("Local host address: " + java.net.InetAddress.getLocalHost().toString());
         }
         System.out.println(SessionEnv.SESSION_MANAGER_URL + " created/bound in registry");
      }
      catch (Exception e)
      {
         e.printStackTrace();
      }
   }
}

