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

  $Archive: /njcl_v2/src/com/novell/service/nds/NdsBackLink.java $
  $Revision: 11 $
  $Modtime: 11/01/01 10:24a $
 
  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.nds;


import java.io.Serializable;

import java.util.Enumeration;
import java.util.Vector;

import com.novell.service.schema.SchemaValue;
import com.novell.service.schema.SchemaComposite;


/**
 * Provides access to values of the Back Link attribute. The
 * Back Link attribute, which is multi-valued, contains the set
 * of servers that stores an external reference to an associated
 * object. It is used internally by NDS to notify such servers
 * of changes in the status of the object.
 * 
 * <p>Matching Rules: Equality</p>
 *
 * @see NdsSyntaxId
 */
public class NdsBackLink
   implements NdsAttributeValue, SchemaComposite, Cloneable, Serializable
{
   private static final int matchingRules = equality;

   private static String[] compositeIds;

   static
   {
      compositeIds = new String[2];
      compositeIds[0] = "remoteId";
      compositeIds[1] = "objectName";
   }

  /**
   * @internal
   */
   protected int remoteId;

  /**
   * @internal
   */
   protected String objectName;

   private String name;


  /**
   * Constructs an NdsBackLink object based on the specified
   * remoteId and objectName parameters.
   *
   * @param remoteId   The external reference identifying the back linked
   *                   object that is valid on the server.
   * @param objectName The server holding the external reference
   *                   (remoteId).
   */
   public NdsBackLink (
         long remoteId,
         String objectName)
   {
      this ("", remoteId, objectName);
   }

  /**
   * @internal
   */
   protected NdsBackLink ()
   {
      remoteId = -1;
      objectName = null;
      name = null;
   }

  /*
   * Private constructor; not documented!
   */
   private NdsBackLink (
         String name,
         long remoteId,
         String objectName)
   {
      this.remoteId = (int) (remoteId & INT_MASK);
      this.objectName = objectName;
      this.name = name;
   }

  /**
   * @internal
   */
   protected NdsBackLink (
         NdsBackLink aBackLink)
   {
      this.remoteId = aBackLink.remoteId;
      this.objectName = aBackLink.objectName;
      this.name = aBackLink.name;
   }


   // ******************** SchemaValue Interface ********************

  /**
   * Compares two Objects for ordering, or compares two strings
   * lexicographically.
   *
   * The compareTo method does not apply to the NdsBacklink syntax
   * because this syntax does not support the ordering and substrings
   * matching rules.
   */
   public int compareTo (
         Object anObject)
      throws Exception
   {
      throw (new Exception ());
   }

  /**
   * Compares two Objects for equality. The equals method compares
   * this object value with the value of the reference object in
   * the anObject parameter.
   *
   * <p>The equals method implements the most discriminating possible
   * equivalence relation on objects; that is, for any reference values
   * X and Y, this method returns TRUE if and only if X and Y refer to
   * the same object (X==Y has the value TRUE).</p>
   * 
   * @param anObject The reference object with which to compare.
   *
   * @return A boolean set to TRUE if and only if the argument is not
   *         NULL and is an NDS integer object that contains the
   *         same value as this object, otherwise set to FALSE.
   */
   public boolean equals (
         Object anObject)
   {
      if ((anObject != null) && (anObject instanceof NdsBackLink))
      {
         NdsBackLink anotherBackLink = (NdsBackLink) anObject;

         if (remoteId == anotherBackLink.getRemoteId ())
         {
            return (false);
         }
         if (false == objectName.equals (anotherBackLink.getObjectName ()))
         {
            return (false);
         }
         return (true);
      }
      return (false);

   }

  /**
   * @internal
   */
   public String getName ()
   {
     return (name);
   }

  /**
   * @internal
   */
   public String getSyntaxId ()
   {
      return (NdsSyntaxId.BACK_LINK);
   }


   // ******************** SchemaComposite Interface ********************

  /**
   * Returns the number of elements in this sequence.
   *
   * @return The number of elements in this sequence as an int.
   */
   public int count ()
   {
      return (compositeIds.length);
   }

   /**
   * Returns a SchemaValue object based on the given passed-in
   * string containing the element value. The SchemaValue object
   * is a Java language data type.
   *
   * @param compositeId Passed-in string containing the element
   *                    value.
   *
   * @return A SchemaValue object containing the remoteId
   *         and objectName, or NULL.
   */
   public SchemaValue getValue (
         String compositeId)
   {
      if (compositeId.equalsIgnoreCase (compositeIds[0]))
      {
         // getRemoteId ();
         return (new NdsInteger (compositeIds[0], remoteId));
      }
      else if (compositeId.equalsIgnoreCase (compositeIds[1]))
      {
         // getObjectName ();
         return (new NdsString (compositeIds[1], objectName));
      }
      return (null);
   }

  /**
   * Returns an enumeration of composite IDs.
   *
   * @return An enumeration of composite IDs.
   */
   public Enumeration getValueIds ()
   {
      Vector compositeIds = new Vector ();

      compositeIds.copyInto (this.compositeIds);
      return (compositeIds.elements ());
   }

  /**
   * Returns an enumeration of the elements in this composite.
   *
   * @return An enumeration of composite elements (remoteID and
   *         objectName).
   */
   public Enumeration getValues ()
   {
      Vector values = new Vector ();

      values.addElement (new NdsInteger (compositeIds[0], remoteId));
      values.addElement (new NdsString (compositeIds[1], objectName));
      return (values.elements ());
   }


   // ******************** NdsAttributeValue Interface ********************

  /**
   * Compares two Objects using the approximate equals matching rule.
   * 
   * The approximate method does not apply to the NdsBacklink syntax
   * because this syntax does not support the approximate equals
   * matching rule.
   */
   public boolean approximate (
         Object anObject)
      throws Exception
   {
      throw (new Exception ());
   }

  /**
   * Returns the int that represents the SyntaxId.
   *
   * @return The syntax ID as an int.
   */
   public int getNdsSyntaxId ()
   {
      return (NdsSyntaxId.BACK_LINK_ID);
   }

  /**
   * Checks to see if this object supports the specified
   * matching rules.
   *
   * <p>The NdsBackLink syntax supports only the equality matching
   * rule.
   *
   * @param matchingRules Set of matching rules to check.
   *
   * @return A boolean set to TRUE if the matching rules for this
   *         object are equal to the matchingRules parameter.
   */
   public boolean supportsMatchingRules (
         int matchingRules)
   {
      if ((matchingRules & this.matchingRules) == matchingRules)
      {
         return (true);
      }
      return (false);
   }


   // ******************** Object Class ********************

  /**
   * Creates a new object of the same class as this object. It
   * then initializes each of the new object's fields by assigning
   * them the same value as the corresponding fields in this object.
   * No constructor is called.
   *
   * @return A clone of this object instance containing the cloned
   *         syntax.
   */
   public Object clone ()
   {
      try
      {
         NdsBackLink backLink = (NdsBackLink) super.clone ();

         backLink.remoteId = this.remoteId;
         backLink.objectName = this.objectName;

         backLink.name = this.name;

         return (backLink);
      }
      catch (CloneNotSupportedException e)
      {
         // this shouldn't happen, since we are Cloneable
         throw (new InternalError ());
      }

   } /* clone () */

  /**
   * Generates and returns a string representation of the object. In
   * general, the toString method returns a string that textually 
   * represent this object. The result should be a concise but
   * informative representation that is easy to read.
   *
   * @return A String representation of the object.
   */
   public String toString ()
   {
      return (String.valueOf (remoteId) + "; " + objectName);
   }


   // ******************** NdsBackLink Class ********************

  /**
   * Returns the reference (remoteId) that is valid on the server.
   *
   * @return The valid reference (remoteId on the server).
   */
   public long getRemoteId ()
   {
      return (remoteId & INT_MASK);
   }

  /**
   * Returns the identity of the server holding the reference
   * (remoteID).
   *
   * @return The identity of the server holding the reference (remoteID).
   */
   public String getObjectName ()
   {
      return (objectName);
   }

} /* NdsBackLink */


