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

  $Archive: /njcl_v2/src/com/novell/service/session/xplat/Connection.java $
  $Revision: 34 $
  $Modtime: 8/21/01 4:04p $

  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.jncp.ClientErrors;
import com.novell.service.jncp.NSIException;
import com.novell.service.jncp.NSIExceptionBuilder;
import com.novell.service.jncpv2.clx.*;
import com.novell.service.session.*;
import com.novell.service.session.nds.NDSServerSessionState;
import com.novell.service.session.xplat.Natives;

import com.novell.service.session.util.Debug;
import java.rmi.server.UID;
import com.novell.service.session.util.JVMUID;
import java.util.NoSuchElementException;
import java.io.Serializable;

/** @internal
 * Hides "native" implementation of NWCONN_HANDLE and operations associated
 * with it.
 */
//public class Connection implements Serializable, Cloneable
public class Connection implements Serializable
{
   // 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;
   static public boolean  DEBUG_FORCE_LOGIN = false;
   final static private boolean  FINALIZER_DEBUG = false;
   final static private boolean  I_DEBUG = false; // Ignore exception
   final static private boolean  S_DEBUG = false; // May have side effects
   final static private boolean  JVMUID_DEBUG = false;
   final static private boolean  OTHER_DEBUG = false;
   final static private boolean  CACHE_DEBUG = false;

   // Print message if deprecated API is used
   final static private boolean ERROR_ON_DEPRECATED = false;
   final private static String INVALID =  "Connection no longer valid";

   protected int reference = 0;
   protected int handle = 0;
   protected boolean isValid = false;
   protected UID uid;

   protected String server = null;
   protected String tree = null;
   protected int owner = Natives.OWNER_NONE;

   protected int hashCode = -1;

   protected Throwable reason;
   protected Throwable ownerTrace;

   private XplatUtil xplatUtil = null;
   private boolean forceLicense = false;


   protected void finalize()
   throws Throwable
   {
      if (DEBUG || FINALIZER_DEBUG)
      {
         Debug.println(this.toString());
      }
      // Java language spec: super.finalize() NOT automatically called
      super.finalize();
      xplatUtil.close(this);
      if (DEBUG || JVMUID_DEBUG)
      {
         JVMUID.getInstance().
            remove(uid);
      }
      if (DEBUG || FINALIZER_DEBUG)
      {
         Debug.println("<-Connection.finalize()");
      }
   }

   private Connection()
   throws SessionException
   {
   }

   protected Connection(
      int reference,
      int handle,
      int owner,
      XplatUtil xplatUtil)
   throws SessionException
   {
      this(reference, handle, null, null, owner, xplatUtil);
   }

   protected Connection(
      int reference,
      int handle,
      String server,
      String tree,
      int owner,
      XplatUtil xplatUtil)
   throws SessionException
   {
      this.xplatUtil = xplatUtil;
      if (DEBUG || OTHER_DEBUG)
         Debug.println("Connection.Connection()");

      if (DEBUG || JVMUID_DEBUG)
      {
         // Assign unique id to this connection
         JVMUID jvmUid = JVMUID.getInstance();
         uid = jvmUid.createUID();
//         jvmUid.write(uid, new Integer(0));
      }

      // Hashcode *based* on reference...but reference could go invalid
      // while we still need hashCode
      this.hashCode = reference;
      this.reference = reference;
      this.handle = handle;

      if (Natives.isNetWareNLM())
      {
         if (DEBUG || DEBUG_FORCE_LOGIN)
            Debug.println("Connection: " + this);
         // This is the equivalent to the clib spil layer's determination
         // of a local connection...all local connections are
         // between 0x20000 && 0x10000
         // Yes, this is a broken check, but it's just as broken in the
         // spil layer
         if (handle <= 0x20000 && handle >= 0x10000)  // If local handle
            forceLicense = true;
         if (DEBUG || DEBUG_FORCE_LOGIN)
            Debug.println("Force = " + forceLicense);
      }

      setOwner(owner);
//      this.owner = owner;
      this.server = server;
      this.tree = DomainName.strip(tree);
//      if (this.tree.length() == 32)
//         Thread.dumpStack();
      this.isValid = true;
      this.reason = null;
   }

   public boolean equals(
      Object obj)
   {
      return xplatUtil.equals(this, (Connection)obj);
   }

   public int hashCode()
   {
      return hashCode;
   }

   public boolean forceLicense()
   {
      return forceLicense;
   }

   public void setServer(
      String server)
   {
      xplatUtil.setServer(
         this,
         server);
   }

   public void setTree(
      String tree)
   {
      xplatUtil.setTree(
         this,
         tree);
   }

   public void checkOwner(
      int owner)
   throws SessionException
   {
      xplatUtil.checkOwner(
         this,
         owner);
   }

   public void setOwner(
      int owner)
   {
      xplatUtil.setOwner(
         this,
         owner);
   }

   public int getOwner()
   {
      return xplatUtil.getOwner(
         this);
   }

   public String getServer()
   throws SessionException
   {
      return xplatUtil.getServer(
         this);
   }

   public String getTree()
   throws SessionException
   {
      return xplatUtil.getTree(
         this);
   }

   public String toString()
   {
      return xplatUtil.toString(
         this);
   }

   public int getReference()
   throws SessionException
   {
      return xplatUtil.getReference(
         this);
   }

   public int getHandle()
   throws SessionException
   {
      return xplatUtil.getHandle(this);
   }

   public void setReason(
      Throwable reason)
   {
      xplatUtil.setReason(
         this,
         reason);
   }

   public Throwable getReason()
   {
      return xplatUtil.getReason(
         this);
   }

   public void keep()
   throws SessionException
   {
      xplatUtil.keep(this);
   }

   public boolean isValid()
   {
      return xplatUtil.isValid(
         this);
   }

   public Object getInfo(
      int infoLevel)
   throws SessionException
   {
      return xplatUtil.getInfo(
         this,
         infoLevel);
   }

   public int getInfoValue(
      int infoLevel)
   throws SessionException
   {
      return xplatUtil.getInfoValue(
         this,
         infoLevel);
   }

   public String getInfoString(
      int infoLevel)
   throws SessionException
   {
      return xplatUtil.getInfoString(
         this,
         infoLevel);
   }

   public Address getInfoAddress()
   throws SessionException
   {
      return xplatUtil.getInfoAddress(
         this);
   }

   public Address getInfoAddress(
      int type)
   throws SessionException
   {
      return xplatUtil.getInfoAddress(
         this,
         type);
   }

   public Version getInfoVersion(
      int infoLevel)
   throws SessionException
   {
      return xplatUtil.getInfoVersion(
         this,
         infoLevel);
   }

   /**
    * Close connection handle.
    */
   public void close()
   throws SessionException
   {
      xplatUtil.close(this);
   }

   /**
    * Close connection reference (system-level close).
    */
   public void closeRef()
   throws SessionException
   {
      xplatUtil.closeRef(this);
   }

   /**
    * @deprecated Use com.novell.service.security and related packages.
    */
   public void login(
      String userName,
      String password)
   throws SessionException
   {
      xplatUtil.login(
         this,
         userName,
         password);
   }

   /**
    * @deprecated Use com.novell.service.security and related packages.
    */
   public void logout()
   throws SessionException
   {
      xplatUtil.logout(this);
   }

   public String getUserName()
   throws SessionException
   {
      return xplatUtil.getUserName(this);
   }

   /**
    * Retrieves the attributes specific to the connection
    */
   public SessionAttrs getAttributes()
   throws SessionException
   {
      return xplatUtil.getAttributes(
         this);
   }

   /**
    * Retrieves the attributes specific to the connection
    */
   public SessionAttrs getAttributes(
      String attrIds[])
   throws SessionException
   {
      return xplatUtil.getAttributes(
         this,
         attrIds);
   }

   public void changePassword(
      String userName,
      String oldPassword,
      String newPassword)
   throws SessionException
   {
      xplatUtil.changePassword(
         this,
         userName,
         oldPassword,
         newPassword);
   }

   public void setPassword(
      String objName,
      int objType,
      String password)
   throws SessionException
   {
      xplatUtil.setPassword(
         this,
         objName,
         objType,
         password);
   }

   public void verifyPassword(
      String objName,
      int objType,
      String password)
   throws SessionException
   {
      xplatUtil.verifyPassword(
         this,
         objName,
         objType,
         password);
   }

   public XplatUtil getUtil()
   {
      return xplatUtil;
   }
}


