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

  $Archive: /njcl_v2rmi/src/com/novell/service/session/xplat/Connections.java $
  $Revision: 9 $
  $Modtime: 1/05/01 4:03p $

  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.xplat;

import com.novell.service.session.util.Debug;
import com.novell.service.jncp.NSIException;
import com.novell.service.jncp.NSIExceptionBuilder;
import com.novell.service.jncpv2r.clx.ClxJNI;
import com.novell.service.jncpv2r.cal.CalJNI;
import com.novell.service.jncpv2r.net.NetJNI;
import com.novell.service.session.SessionAttr;
import com.novell.service.session.SessionAttrEnumerator;
import com.novell.service.session.SessionAttrs;
import com.novell.service.session.SessionEnv;
import com.novell.service.session.SessionException;
import com.novell.service.session.spi.SessionManagerImpl;
import com.novell.service.session.SessionManagerFactory;
import com.novell.service.session.SessionRuntimeException;
import com.novell.service.session.InvalidDomainNameException;
import com.novell.service.session.InvalidUserNameException;
import com.novell.service.session.util.TwoWayHashtable;
import com.novell.service.toolkit.jcl.NWLong;
import com.novell.service.toolkit.jcl.NWVersion;
import com.novell.java.lang.IntegerBuffer;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.NoSuchElementException;
import java.util.Vector;
import java.io.Serializable;
//import com.novell.java.util.RWLock;
//import com.novell.java.util.Mutex;

/** @internal
 * Utility class shared by NDS and Bindery Session providers.
 */
public class Connections implements Cloneable
{
   // 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  CONN_DEBUG = false;

   private TwoWayHashtable connections;
//   private RWLock rwLock;
//   private Mutex mutex;

   /** @internal
    *
    * A boolean flag indicating whether or not the environment is shared.
    */
   protected boolean shared;

   Connections()
   {
      shared = true;
      connections = new TwoWayHashtable();
//      rwLock = new RWLock();
//      mutex = new Mutex();
   }

   public Connection put(
      Connection conn)
   throws SessionException
   {
      // CAUTION: Don't call other put from here...you'll loose other info
      // in Connection object...esp. the owner, tree, server
      if (CONN_DEBUG || DEBUG)
      {
         Debug.println("HASH: 0x" +
            Integer.toHexString(
               conn.hashCode()));
      }
      Integer ref = new Integer(
         conn.reference);
      return(Connection)connections.put(ref, conn);
   }

   public Connection get(
      Connection conn)
   throws SessionException
   {
      if (CONN_DEBUG || DEBUG)
      {
         Debug.println("HASH: 0x" +
            Integer.toHexString(
               conn.hashCode()));
      }
      return (this.get(
         conn.reference));
   }

   public Connection get(
      int reference)
   throws SessionException
   {
      Integer ref = new Integer(reference);
      return(Connection)connections.get(ref);
   }

//   synchronized public int getKey(
   public int getKey(
      Connection value)
   {
      if (CONN_DEBUG || DEBUG)
      {
         Debug.println("HASH: 0x" +
            Integer.toHexString(
               value.hashCode()));
      }
      return((Integer)connections.get(value)).
         intValue();
   }

//   synchronized public Object remove(
   public Object remove(
      Connection conn)
   {
      if (CONN_DEBUG || DEBUG)
      {
         Debug.println("HASH: 0x" +
            Integer.toHexString(
               conn.hashCode()));
      }
      return connections.removeByValue(conn);
   }

   public Object remove(
      int reference)
   {
      Integer ref = new Integer(reference);
      return remove(ref);
   }

   public Object remove(
      Integer reference)
   {
      return(Connection)connections.remove(reference);
   }

//   synchronized public void open(
   public void open(
      int reference)
   {
      Integer ref = new Integer(reference);
      Connection conn = (Connection)connections.get(ref);
   }

//   synchronized public boolean containsKey(
   public boolean containsKey(
      Connection conn)
   throws SessionException
   {
      if (CONN_DEBUG || DEBUG)
      {
         Debug.println("HASH: 0x" +
            Integer.toHexString(
               conn.hashCode()));
      }
      return (this.containsKey(
         conn.reference));
   }

//   synchronized public boolean containsKey(
   public boolean containsKey(
      int reference)
   {
      Integer ref = new Integer(reference);
      return (containsKey(ref));
   }

//   synchronized public boolean containsKey(
   public boolean containsKey(
      Integer reference)
   {
      return (connections.containsKey(reference));
   }

//   synchronized public boolean contains(
   public boolean contains(
      Connection value)
   {
      if (CONN_DEBUG || DEBUG)
      {
         Debug.println("HASH: 0x" +
            Integer.toHexString(
               value.hashCode()));
      }
      return (connections.contains(value));
   }

   public ConnectionEnumerator elements()
   {
      return (new ConnectionEnumerator(connections.elements()));
   }

//   synchronized public String toString()
   public String toString()
   {
      return connections.toString();
   }
   /**
    * Creates a new copy of this container. The container is
    * shared until a modification is made to the clone.
    *
    * <p>For more information on this Object, see Sun's java.lang.Cloneable
    * class.
    *
    * @return  A clone of this Connections object.
    */
//   synchronized public Object clone ()
   public Object clone ()
   {
      try
      {
         Connections clone = (Connections) super.clone ();

         clone.connections = this.connections;
         setShared();
         clone.setShared();
         return (clone);
      }
      catch (CloneNotSupportedException e)
      {
         // this shouldn't happen, since we are Cloneable
         throw (new InternalError ());
      }
   }

   /** @internal
    *
    * Allows a SessionEnv to be efficiently share. it should be
    * called when a sub-class shares the same Hashtable.
    */
//   synchronized protected final void setShared ()
   protected final void setShared ()
   {
      shared = true;
   }

   /*
    * Copies the connections if it is shared.
    */
   private final void copyWhenShared ()
   {
      if (shared)
      {
         setConnections(
            (TwoWayHashtable)getConnections().
               clone ());
         shared = false;
      }

   } /* copyWhenShared () */

   /** @internal
    *
    * Sets the connections hashtable.
    *
    * @param connections The connections hashtable to be set.
    */
   // Make sure get/set synchronized...avoid read/write synch problems.
//   synchronized protected void setConnections(TwoWayHashtable connections)
   protected void setConnections(TwoWayHashtable connections)
   {
      this.connections = connections;
   }

   /** @internal
    *
    * Returns the connections hashtable.
    *
    * @return The Hashtable for the connections.
    */
   // Make sure get/set synchronized...avoid read/write synch problems.
//   synchronized protected TwoWayHashtable getConnections()
   protected TwoWayHashtable getConnections()
   {
      return this.connections;
   }

   public int size()
   {
      return this.connections.size();
   }

/*
   protected void lockRead()
   {
//      rwLock.lockRead();
//      mutex.acquire(60000);
   }

   protected void lockWrite()
   {
//      rwLock.lockWrite();
//      mutex.acquire(60000);
   }

   protected void unlock()
   {
//      rwLock.unlock();
//      mutex.release();
   }
*/

} // class Connections

