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

  $Archive: /njcl_v2/src/com/novell/service/server/ServerVersionsImpl.java $
  $Revision: 11 $
  $Modtime: 1/28/00 12:44p $
 
  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.server;

import javax.naming.*;
import javax.naming.directory.*;
import com.novell.service.jncp.*;
import com.novell.service.session.*;
import com.novell.service.session.xplat.*;
import com.novell.service.rfc1960.SearchStringComponent;

/**
 * Provides the attribute value of a ServerDirContext.
 *
 * <p>This attribute supports expanded search capabilities. Use the
 * setSearchFields() and getSearchFields() methods to control which
 * fields are used when performing a search. If the searchFields are
 * not explicitly set, then all fields are used by default.
 *
 * @see ServerVersions
 */
public class ServerVersionsImpl implements
com.novell.utility.naming.directory.StaticAttributeValue,
com.novell.service.server.ServerVersions
{
   private byte majorVersion;
   private byte minorVersion;
   private byte revision;
   private byte accountVersion;
   private byte queueVersion;
   private byte printVersion;
   private byte virtualConsoleVersion;
   private byte securityVersion;
   private byte internetBridgeVersion;
   private boolean empty = true;
   private Session session;
   private int searchFields = -1; //all bits on

  /**
   * Constructs a ServerVersionImpl attribute value. This constructor
   * is used to manually create attributes for methods such as search().
   */
   public ServerVersionsImpl()
   {
   }

   /** @internal
   * Constructs this attribute value and stores the session to the server.
   * This constructor is for use by ServerDirContext
   * @param session The session to the server this attribute is for.
   */
   protected ServerVersionsImpl(
         Session session)
   {
      this.session = session;
   }

  /**
   * Sets the fields to be used when performing a search. Use the
   * constants defined in the ServerVersion interface as the value
   * of the fields parameter. Multiple fields can be bitwise OR'ed
   * together to search on multiple fields.
   *
   * @param fields The fields to be used in the search.
   *
   * @see ServerVersions
   */
   public void setSearchFields(
         int fields)
   {
      searchFields = fields;
   }

  /**
   * Returns the fields currently set to be used when performing
   * a search.
   *
   * @return The search fields currently set.
   */
   public int getSearchFields()
   {
      return searchFields;
   }

  /**
   * Returns the major version of the server.
   *
   * @return The major version number.
   *
   * @exception NSIException Standard NJCL exception for working on
   *                         top of Xplat libraries.
   */
   public byte getMajorVersion() throws NSIException
   {
      if(empty)
         getFileServerVersionInfo();
      return majorVersion;
   }

  /**
   * Returns the minor version of the server.
   *
   * @return The minor version number.
   *
   * @exception NSIException Standard NJCL exception for working on
   *                         top of Xplat libraries.
   */
   public byte getMinorVersion() throws NSIException
   {
      if(empty)
         getFileServerVersionInfo();
      return minorVersion;
   }

  /**
   * Returns the revision number of the server.
   *
   * @return The revision number.
   *
   * @exception NSIException Standard NJCL exception for working on
   *                         top of Xplat libraries.
   */
   public byte getRevision() throws NSIException
   {
      if(empty)
         getFileServerVersionInfo();
      return revision;
   }

  /**
   * Returns the account version of the server.
   *
   * @return The account version number.
   *
   * @exception NSIException Standard NJCL exception for working on
   *                         top of Xplat libraries.
   */
   public byte getAccountVersion() throws NSIException
   {
      if(empty)
         getFileServerVersionInfo();
      return accountVersion;
   }

  /**
   * Returns the queue version number of the server.
   *
   * @return  The queue version number.
   *
   * @exception NSIException Standard NJCL exception for working on
   *                         top of Xplat libraries.
   */
   public byte getQueueVersion() throws NSIException
   {
      if(empty)
         getFileServerVersionInfo();
      return queueVersion;
   }

  /**
   * Returns the print version number of the server.
   *
   * @return The print version number.
   *
   * @exception NSIException Standard NJCL exception for working on
   *                         top of Xplat libraries.
   */
   public byte getPrintVersion() throws NSIException
   {
      if(empty)
         getFileServerVersionInfo();
      return printVersion;
   }

  /**
   * Returns the virtual console version number of the server.
   *
   * @return  The virtual console version number.
   *
   * @exception NSIException Standard NJCL exception for working on
   *                         top of Xplat libraries.
   */
   public byte getVirtualConsoleVersion() throws NSIException
   {
      if(empty)
         getFileServerVersionInfo();
      return virtualConsoleVersion;
   }

  /**
   * Returns the security version number of the server.
   *
   * @return  The security version number.
   *
   * @exception NSIException Standard NJCL exception for working on
   *                         top of Xplat libraries.
   */
   public byte getSecurityVersion() throws NSIException
   {
      if(empty)
         getFileServerVersionInfo();
      return securityVersion;
   }

  /**
   * Returns the Internet bridge version number of the server.
   *
   * @return  The Internet bridge version number.
   *
   * @exception NSIException Standard NJCL exception for working on
   *                         top of Xplat libraries.
   */
   public byte getInternetBridgeVersion() throws NSIException
   {
      if(empty)
         getFileServerVersionInfo();
      return internetBridgeVersion;
   }

  /**
   * Sets the major version number of the server as the search value.
   * This is used to search for all servers matching the value parameter.
   *
   * @param value The major version number.
   *
   * @exception NSIException Standard NJCL exception for working on
   *                         top of Xplat libraries.
   */
   public void setMajorVersion(
         byte value)
      throws NSIException
   {
      if(empty)
         getFileServerVersionInfo();
      majorVersion = value;
   }

  /**
   * Sets the minor version number of the server as the search value.
   * This is used to search for all servers matching the value parameter.
   *
   * @param value The minor version number.
   *
   * @exception NSIException Standard NJCL exception for working on
   *                         top of Xplat libraries.
   */
   public void setMinorVersion(
         byte value)
      throws NSIException
   {
      if(empty)
         getFileServerVersionInfo();
      minorVersion = value;
   }

  /**
   * Sets the revision number of the server as the search value.
   * This is used to search for all servers matching the value parameter.
   *
   * @param value The revision number.
   *
   * @exception NSIException Standard NJCL exception for working on
   *                         top of Xplat libraries.
   */
   public void setRevision(
         byte value)
      throws NSIException
   {
      if(empty)
         getFileServerVersionInfo();
      revision = value;
   }

  /**
   * Sets the account version number of the server as the search value.
   * This is used to search for all servers matching the value parameter.
   *
   * @param value The account version number.
   *
   * @exception NSIException Standard NJCL exception for working on
   *                         top of Xplat libraries.
   */
   public void setAccountVersion(
         byte value)
      throws NSIException
   {
      if(empty)
         getFileServerVersionInfo();
      accountVersion = value;
   }

  /**
   * Sets the minor queue version number of the server as the search value.
   * This is used to search for all servers matching the value parameter.
   *
   * @param value The queue version number.
   *
   * @exception NSIException Standard NJCL exception for working on
   *                         top of Xplat libraries.
   */
   public void setQueueVersion(
         byte value)
      throws NSIException
   {
      if(empty)
         getFileServerVersionInfo();
      queueVersion = value;
   }

  /**
   * Sets the print version number of the server as the search value.
   * This is used to search for all servers matching the value parameter.
   *
   * @param value The print version number.
   *
   * @exception NSIException Standard NJCL exception for working on
   *                         top of Xplat libraries.
   */
   public void setPrintVersion(
         byte value)
      throws NSIException
   {
      if(empty)
         getFileServerVersionInfo();
      printVersion = value;
   }

  /**
   * Sets the virtual console version number of the server as the search
   * value. This is used to search for all servers matching the value
   * parameter.
   *
   * @param value The virtual console version number.
   *
   * @exception NSIException Standard NJCL exception for working on
   *                         top of Xplat libraries.
   */
   public void setVirtualConsoleVersion(
         byte value)
      throws NSIException
   {
      if(empty)
         getFileServerVersionInfo();
      virtualConsoleVersion = value;
   }

  /**
   * Sets the security version number of the server as the search
   * value. This is used to search for all servers matching the value
   * parameter.
   *
   * @param value The security version number.
   *
   * @exception NSIException Standard NJCL exception for working on
   *                         top of Xplat libraries.
   */
   public void setSecurityVersion(
         byte value)
      throws NSIException
   {
      if(empty)
         getFileServerVersionInfo();
      securityVersion = value;
   }

  /**
   * Sets the Internet bridge version number of the server as the search
   * value. This is used to search for all servers matching the value
   * parameter.
   *
   * @param value The Internet bridge version number.
   *
   * @exception NSIException Standard NJCL exception for working on
   *                         top of Xplat libraries.
   */
   public void setInternetBridgeVersion(
         byte value)
      throws NSIException
   {
      if(empty)
         getFileServerVersionInfo();
      internetBridgeVersion = value;
   }

   /**
   * Get service from the session and fill in the instance values
   */
   private void getFileServerVersionInfo() throws NSIException
   {
      empty = false;
      //only call if valid session. This allows users to new()
      // instances of this class for search()
      if(session == null)
         return;
      CVersionInfo info = new CVersionInfo();
      try
      {
         ((CallsService)session.getService(
            CallsService.KEY)).getFileServerVersionInfo(info);
      }
      catch(Exception e)
      {
         throw NSIExceptionBuilder.build(e);
      }

      majorVersion = (byte) info.iFileVersion;
      minorVersion = (byte) info.iFileSubVersion;
      revision = (byte) info.iRevision;
      accountVersion = (byte) info.iAccountVersion;
      queueVersion = (byte) info.iQueueVersion;
      printVersion = (byte) info.iPrintVersion;
      virtualConsoleVersion = (byte) info.iVirtualConsoleVersion;
      securityVersion = (byte) info.iSecurityVersion;
      internetBridgeVersion = (byte) info.iInternetBridgeVersion;
   }

   /** @internal
   */   
   public Attribute buildAttribute() throws NamingException
   {
      return new BasicAttribute(ATTR_ID, this);
   }

   /** @internal
   */   
   public String getID()
   {
      return ATTR_ID;
   }

   /** @internal
   */   
   public boolean compare(
         SearchStringComponent ssc)
      throws NamingException
   {
      int opType = ssc.getOperationType();
      if(opType == SearchStringComponent.PRESENT)
         return true;
      if(opType == SearchStringComponent.EQUALS)
         return equals(ssc.getReplacementObject());
      return false;
   }

   /** @internal
   */   
   public boolean equals(
         Object compObject)
   {
      if(compObject== null || !(compObject instanceof ServerVersionsImpl) )
         return false;
      ServerVersionsImpl obj = (ServerVersionsImpl)compObject;
      if(obj == this)
         return true;
      try
      {
         if(empty)
            getFileServerVersionInfo();

         int fields = obj.getSearchFields();
         //Check only fields that are set in searchfields. looks complicated but is effecient because
         //conditional AND's perform early out logic and only calls get() functions if necessary
         if(((fields & MAJOR_VERSION) != 0 ? majorVersion == obj.getMajorVersion() : true) &&
            ((fields & MINOR_VERSION) != 0 ? minorVersion == obj.getMinorVersion() : true) &&
            ((fields & REVISION) != 0 ? revision == obj.getRevision() : true) &&
            ((fields & ACCOUNT_VERSION) != 0 ? accountVersion == obj.getAccountVersion() : true) &&
            ((fields & QUEUE_VERSION) != 0 ? queueVersion == obj.getQueueVersion() : true) &&
            ((fields & PRINT_VERSION) != 0 ? printVersion == obj.getPrintVersion() : true) &&
            ((fields & VIRTUAL_CONSOLE_VERSION) != 0 ? virtualConsoleVersion == obj.getVirtualConsoleVersion() : true) &&
            ((fields & SECURITY_VERSION) != 0 ? securityVersion == obj.getSecurityVersion() : true) &&
            ((fields & INTERNET_BRIDGE_VERSION) != 0 ? internetBridgeVersion == obj.getInternetBridgeVersion() : true) )
         {
            return true;
         }
         return false;
      }
      catch(NSIException e)
      {
         return false;
      }
   }

   // Server does not support modifying attributes
   // so all of the following methods are not supported.
   /** @internal
   */   
   public void addAttribute(
         Attribute attr)
   throws NamingException
   {
      throw new javax.naming.directory.AttributeModificationException();
   }

   /** @internal
   */   
   public void deleteAttribute(
         Attribute attr)
   throws NamingException
   {
      throw new javax.naming.directory.AttributeModificationException();
   }

   /** @internal
   */   
   public void modifyAttribute(
         Attribute attr)
   throws NamingException
   {
      throw new javax.naming.directory.AttributeModificationException();
   }

   /** @internal
   */   
   public boolean hasMoreElements()
   {
      return false;
   }

   /** @internal
   */   
   public Object nextElement()
   {
      throw new java.util.NoSuchElementException();
   }

   /** @internal
   */   
   public Object getStaticInterface()
   {
      return this;
   }
}
