//     $Id: Depend.java,v 3.2 1998/12/14 22:23:03 te3d Exp $    
 ////////////////////////////////////////////////////////////////////////////
 //
 // File: Depend.java
 //
 // Purpose: A Depend (dependency) is directional, from a source
 //          Node (FR or DP) within one Module to a destination Node
 //          within the same or different Module.
 //
 //          Each Depend has a probability associated with it; if
 //          the source Node is unstable, this is the probability
 //          that it forces the destination Node to destabilize as
 //          well.
 //
 //          This is a base class, and can used by several
 //          modules.  For that reason, we don't bother
 //          specifying the Invoking modules.
 //
 // Authors:
 //   txe  Travis Emmitt  emmitt@virginia.edu
 //
 // Modifications:
 //   28-OCT-1998  txe  (v2) Initial creation
 //   03-NOV-1998  txe  Added comments, removed unused methods.
 //   04-NOV-1998  jpg  Added Seraization methods
 //   06-NOV-1998  rgb  Added version control header info
 //   06-NOV-1998  txe  Added Valid(), Verbose()
 //   06-NOV-1998  jpg  implements Serializable
 //   09-NOV-1998  jpg  cleaned up style
 //
 //   13-NOV-1998  txe  (v2) Removed Die, added exceptions
 //   15-NOV-1998  txe  Improved Exceptions, comments, add version, paranoid
 //
 //   30-NOV-1998  txe  (v3) Improved format, removed version
 //   14-DEC-1998  txe  Disabled paranoid test
 //
 ////////////////////////////////////////////////////////////////////////////
 import java.util.*;
 public class Depend implements java.io.Serializable {
   protected int source_module_id;   // index of source module
   protected int source_node_id;        // index of source node within its module
   protected int dest_module_id;        // index of destination module
   protected int dest_node_id;        // index of dest node within its module
   protected double probability;        // probability that source affects dest
   private String delim = " ";       // token deliminator for serialization
   private boolean paranoid = false; // if true, check against ToSerial()
   ///////////////////////////////////////////////////////////////////
   //
   // Method:  Depend  [constructor]
   //
   // Purpose: Default constructor, you shouldn't use it.
   //          
   ///////////////////////////////////////////////////////////////////
   public Depend () {}
   ///////////////////////////////////////////////////////////////////
   //
   // Method:  Depend  [constructor]
   //
   // Purpose: Creates a new Depend as a copy of the specified Depend.
   //          
   ///////////////////////////////////////////////////////////////////
   public Depend (Depend new_depend)
   throws BoundsException, NullException {
     Copy (new_depend);
   }
   ///////////////////////////////////////////////////////////////////
   //
   // Method:  Depend  [constructor]
   //
   // Purpose: This creates a new Depend(ency) between the
   //          two specified Nodes, with the specified
   //          probability.  The Nodes are specified by their
   //          module index and node index within that module.
   //   
   ///////////////////////////////////////////////////////////////////
   public Depend (int new_source_module_id, int new_source_node_id,
          int new_dest_module_id,   int new_dest_node_id,
          double new_probability)
   throws BoundsException {
     SetSource      (new_source_module_id, new_source_node_id);
     SetDest        (new_dest_module_id,   new_dest_node_id);
     SetProbability (new_probability);
     Validate ();
   }
   ///////////////////////////////////////////////////////////////////
   //
   // Method:  Depend  [constructor]
   //
   // Purpose: This creates a new Depend(ency) between the
   //          two specified Nodes, with the specified
   //          probability.  The Nodes are specified by their
   //          module index and node index within that module.
   //          Data is read from a string form:
   //          smiDsniDdmiDdniDprobD 
   //   
   ///////////////////////////////////////////////////////////////////
   public Depend (String source)
   throws BoundsException, EqualityException, NullException, ParsingException {
     if (source == null) {
       throw new NullException ("source");
     }
     try {
       StringTokenizer st = new StringTokenizer (source, delim);
       SetSource (new Integer (st.nextToken()).intValue(),
          new Integer (st.nextToken()).intValue());
       SetDest   (new Integer (st.nextToken()).intValue(),
          new Integer (st.nextToken()).intValue());
       SetProbability (new Double (st.nextToken()).doubleValue());
     }
     catch (BoundsException e) {
       throw e;
     }
     catch (Exception e) {
       throw new ParsingException ("Depend string", source);
     }
     // check that output format is consistent with input format:
     if (paranoid) {
       String output = ToSerial ();
       if (!source.equalsIgnoreCase (output)) {
     throw new EqualityException ("Depend string", source, output);
       }
     }
     Validate ();
   }
   ///////////////////////////////////////////////////////////////////
   //
   // Method:  Copy
   //
   // Purpose: Copies the specified Depends's data into this Depend.
   //   
   ///////////////////////////////////////////////////////////////////
   public void Copy (Depend new_depend)
   throws BoundsException, NullException {
     if (new_depend == null) {
       throw new NullException ("new_depend");
     }
     new_depend.Validate ();
     SetSource      (new_depend.GetSourceModuleID(), new_depend.GetSourceNodeID());
     SetDest           (new_depend.GetDestModuleID(),   new_depend.GetDestNodeID());
     SetProbability (new_depend.GetProbability());
     Validate ();
   }
   ///////////////////////////////////////////////////////////////////
   //
   // Method:  GetDestModuleID
   //
   // Purpose: This returns the id of the destination Module.
   //   
   // Note:    Please use the second method; it's more appropriately
   //          named.
   //
   ///////////////////////////////////////////////////////////////////
   public int GetDestModule () {
     return dest_module_id;
   }
   public int GetDestModuleID () {
     return dest_module_id;
   }
   ///////////////////////////////////////////////////////////////////
   //
   // Method:  GetDestNodeID
   //
   // Purpose: This returns the id of the destination Node.
   //   
   // Note:    Please use the second method; it's more appropriately
   //          named.
   //
   ///////////////////////////////////////////////////////////////////
   public int GetDestNode () {
     return dest_node_id;
   }
   public int GetDestNodeID () {
     return dest_node_id;
   }
   ///////////////////////////////////////////////////////////////////
   //
   // Method:  GetProbability
   //
   // Purpose: This returns the probability for the dependency.
   //   
   ///////////////////////////////////////////////////////////////////
   public double GetProbability () {
     return probability;
   }
   ///////////////////////////////////////////////////////////////////
   //
   // Method:  GetSourceModuleID
   //
   // Purpose: This returns the id of the source Module.
   //   
   // Note:    Please use the second method; it's more appropriately
   //          named.
   //
   ///////////////////////////////////////////////////////////////////
   public int GetSourceModule () {
     return source_module_id;
   }
   public int GetSourceModuleID () {
     return source_module_id;
   }
   ///////////////////////////////////////////////////////////////////
   //
   // Method:  GetSourceNodeID
   //
   // Purpose: This returns the id of the source Node.
   //   
   // Note:    Please use the second method; it's more appropriately
   //          named.
   //
   ///////////////////////////////////////////////////////////////////
   public int GetSourceNode () {
     return source_node_id;
   }
   public int GetSourceNodeID () {
     return source_node_id;
   }
   ///////////////////////////////////////////////////////////////////
   //
   // Method:  SetDest
   //
   // Purpose: This sets the destination to the specified Node.
   //   
   ///////////////////////////////////////////////////////////////////
   public void SetDest (int new_module_id, int new_node_id)
   throws BoundsException {
     if (new_module_id < 0) {
       throw new BoundsException ("new_module_id", new_module_id, 0);
     }
     if (new_node_id < 0) {
       throw new BoundsException ("new_node_id", new_node_id, 0);
     }
     dest_module_id = new_module_id;
     dest_node_id   = new_node_id;
   }
   ///////////////////////////////////////////////////////////////////
   //
   // Method:  SetProbability
   //
   // Purpose: This sets the probability to the specified value.
   //          The probability must be between 0 and 1.
   //   
   ///////////////////////////////////////////////////////////////////
   public void SetProbability (double new_probability)
   throws BoundsException {
     if (new_probability < 0 || new_probability > 1) {
       throw new BoundsException ("new_probability", new_probability, 0, 1);
     }
     probability = new_probability;
   }
   ///////////////////////////////////////////////////////////////////
   //
   // Method:  SetSource
   //
   // Purpose: This sets the source to the specified Node.
   //   
   ///////////////////////////////////////////////////////////////////
   public void SetSource (int new_module_id, int new_node_id)
   throws BoundsException {
     if (new_module_id < 0) {
       throw new BoundsException ("new_module_id", new_module_id, 0);
     }
     if (new_node_id < 0) {
       throw new BoundsException ("new_node_id", new_node_id, 0);
     }
     source_module_id = new_module_id;
     source_node_id   = new_node_id;
   }
   ///////////////////////////////////////////////////////////////////
   //
   // Method:  toSerial
   //
   // Purpose: Returns a String representation of the Depend.
   //   
   ///////////////////////////////////////////////////////////////////
   public String ToSerial () {
     return "" + source_module_id + delim + source_node_id + delim
        + dest_module_id + delim + dest_node_id + delim + probability;
   }
   ///////////////////////////////////////////////////////////////////
   //
   // Method:  Valid
   //
   // Purpose: Returns true if Depend is valid, false otherwise.
   //   
   ///////////////////////////////////////////////////////////////////
   public boolean Valid () {
     try {
       Validate();
       return true;
     }
     catch (Exception e) {
       return false;
     }
   }
   ///////////////////////////////////////////////////////////////////
   //
   // Method:  Validate
   //
   // Purpose: Throws an exception if the Depend is invalid.
   //   
   ///////////////////////////////////////////////////////////////////
   public void Validate ()
   throws BoundsException {
     if (source_module_id < 0) {
       throw new BoundsException ("source_module_id", source_module_id, 0);
     }
     if (source_node_id < 0) {
       throw new BoundsException ("source_node_id",   source_node_id,   0);
     }
     if (dest_module_id < 0) {
       throw new BoundsException ("dest_module_id",   dest_module_id,   0);
     }
     if (dest_node_id < 0) {
       throw new BoundsException ("dest_node_id",     dest_node_id,     0);
     }
     if (probability < 0 || probability > 1) {
       throw new BoundsException ("probability", probability, 0, 1);
     }
   }
   ///////////////////////////////////////////////////////////////////
   //
   // Method:  Verbose
   //
   // Purpose: Returns a human-readable String representation of Depend.
   //   
   ///////////////////////////////////////////////////////////////////
   public String Verbose () {
     return "Depend: (" + source_module_id + "." + source_node_id + "-->"
                        + dest_module_id   + "." + dest_node_id
                        + ", probability = " + probability + ")\n";
   }
 }
 ////////////////////////////////////////////////////////////////////////////