home *** CD-ROM | disk | FTP | other *** search
/ Symantec Visual Cafe for Java 2.5 / symantec-visual-cafe-2.5-database-dev-edition.iso / VCafe / prosrc.bin / Matrix.java < prev    next >
Encoding:
Java Source  |  1998-03-18  |  14.1 KB  |  504 lines

  1. /*
  2.  * Copyright (c) 1996 Krumel & Associates, Inc. All Rights Reserved.
  3.  *
  4.  * www.krumel.com - controls@krumel.com
  5.  *
  6.  * Permission is given to the buyer of this package for one software
  7.  * developer to use this software on one CPU (one workstation) and to make
  8.  * one backup copy.  You may uitilize and/or midfy this class for use in your
  9.  * projects.  You may distribute or sell any executable which results from
  10.  * using this code in yur application, except a utility or class of similar
  11.  * nature to this product.  You may distribute this this product in compiled
  12.  * form only, but soley to be used with your cmpiled executable product
  13.  * for the puposes of dynamic loading. You may NOT redistribute the source
  14.  * code in any form or make it accessible through a network or other
  15.  * distribution media to others. Please refer to the file "copyright.html"
  16.  * for further important copyright and licensing information.
  17.  *
  18.  * The source code is the confidential and proprietary information
  19.  * of Krumel & Associates, Inc. ("Confidential Information").  You shall
  20.  * not disclose such Confidential Information and shall use it only in
  21.  * accordance with the terms of the license agreement you entered into
  22.  * with Krumel & Associates, Inc..
  23.  
  24.  * KRUMEL & ASSOCIATES MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE
  25.  * SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT
  26.  * NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  27.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. KRUMEL & ASSOCIATES SHALL NOT
  28.  * BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING,
  29.  * MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  30.  */
  31.  
  32. package symantec.itools.db.awt.genutil;
  33.  
  34. import java.util.Vector;
  35.  
  36. /**
  37.  * Class represents an element of a matrix. Each element contains a pointer to
  38.  * the next element. The matrix class maintains a pointer to the first element
  39.  * of a row and uses that element to manipulate row data.
  40.  */
  41. class MatrixElement implements java.io.Serializable {
  42.     int col;
  43.     Object obj;
  44.     MatrixElement next;
  45.  
  46.     /**
  47.      * Sentinal to indicate no data in row.
  48.      */
  49.     static Object NO_ELEMENT = new Object();
  50.  
  51.     /**
  52.      * Creates a new element with next element set to null.
  53.      */
  54.     MatrixElement(int c, Object o) {
  55.         this(c, o, null);
  56.     }
  57.  
  58.     /**
  59.      * Creates a new element which has a next element
  60.      */
  61.     MatrixElement(int c, Object o, MatrixElement e) {
  62.         col = c;
  63.         obj = o;
  64.         next = e;
  65.     }
  66.  
  67.     /**
  68.      * Creates a deep copy of this row.
  69.      */
  70.     MatrixElement cloneRow() {
  71.         MatrixElement head = new MatrixElement(col, obj);
  72.         MatrixElement curr = head;
  73.         MatrixElement nextElt = next;
  74.  
  75.         while(nextElt!=null) {
  76.             curr.next = new MatrixElement(nextElt.col, nextElt.obj);
  77.             curr = curr.next;
  78.             nextElt = nextElt.next;
  79.         }
  80.  
  81.         return head;
  82.     }
  83.  
  84.     /**
  85.      * Determines if row is contains any data
  86.      */
  87.     final boolean isValid() {
  88.         return obj != NO_ELEMENT;
  89.     }
  90.  
  91.     /**
  92.      * Determine if row contains element
  93.      */
  94.     final boolean contains(int c, Object o) {
  95.         MatrixElement elt = find(c);
  96.  
  97.         if (elt == null || elt.obj == null) {
  98.             return false;
  99.         }
  100.  
  101.         return elt.obj.equals(o);
  102.     }
  103.  
  104.     /**
  105.      * Determine if row contains element
  106.      */
  107.     final boolean contains(int c) {
  108.         return find(c) != null;
  109.     }
  110.  
  111.     /**
  112.      * Sets the object at the specified column. If element already exists, replaces it.
  113.      */
  114.     final void set(int c, Object o) {
  115.         MatrixElement elt = this;
  116.  
  117.         do {
  118.             if (c==elt.col) {
  119.                 //elt is the column so change object
  120.                 elt.obj = o;
  121.                 return;
  122.             } else if (c<elt.col) {
  123.                 //element occurs before this column so insert element
  124.                 elt.next = new MatrixElement(elt.col, elt.obj, elt.next);
  125.                 elt.col = c;
  126.                 elt.obj = o;
  127.                 return;
  128.             } else if (elt.next==null) {
  129.                 elt.next = new MatrixElement(c, o);
  130.             }
  131.  
  132.             elt = elt.next;
  133.         } while (elt != null);
  134.     }
  135.  
  136.     final void unset(int c) {
  137.         MatrixElement elt = find(c);
  138.  
  139.         if (elt == null) {
  140.             return;
  141.         }
  142.  
  143.         if (elt==this && next==null) {
  144.             obj = NO_ELEMENT;
  145.         } else if (elt==this) {
  146.             col = next.col;
  147.             obj = next.obj;
  148.             next = next.next;
  149.         } else {
  150.             if (elt.next==null) {
  151.                 MatrixElement prev = findPrev(c);
  152.                 prev.next = null;
  153.             } else {
  154.                 elt.col = elt.next.col;
  155.                 elt.obj = elt.next.obj;
  156.                 elt.next = elt.next.next;
  157.             }
  158.         }
  159.     }
  160.  
  161.     /**
  162.      * Gets the object in the column. Return null if column value not present
  163.      */
  164.     final Object objectAt(int c) {
  165.         MatrixElement elt = find(c);
  166.  
  167.         if (elt == null) {
  168.             return null;
  169.         }
  170.  
  171.         return elt.obj;
  172.     }
  173.  
  174.     final MatrixElement find(int c) {
  175.         MatrixElement elt = this;
  176.  
  177.         do {
  178.             if (c == elt.col) {
  179.                 return elt;
  180.             } else if (c < elt.col || elt.next == null) {
  181.                 return null;
  182.             }
  183.  
  184.             elt = elt.next;
  185.         } while (elt != null);
  186.  
  187.         return null;
  188.     }
  189.  
  190.     final MatrixElement findPrev(int c) {
  191.         MatrixElement elt = this;
  192.         MatrixElement prev = this;
  193.  
  194.         do {
  195.             if (c == elt.col) {
  196.                 return prev;
  197.             } else if (c < elt.col) {
  198.                 return prev;
  199.             } else if (elt.next == null) {
  200.                 return elt;
  201.             }
  202.  
  203.             prev = elt;
  204.             elt = elt.next;
  205.         } while (elt != null);
  206.  
  207.         return prev;
  208.     }
  209.  
  210.     public final String toString() { return obj.toString(); }
  211. }
  212.  
  213. /**
  214.  * A two-dimensional sparse vector of objects.
  215.  *
  216.  * @version 1.1   Jun2 2, 1997
  217.  * @author  Andy Krumel
  218.  */
  219. public class Matrix implements Cloneable, java.io.Serializable {
  220.     Vector rows = new Vector();
  221.  
  222.     /**
  223.      * Constructs a new empty matrix.
  224.      */
  225.     public Matrix() {
  226.     }
  227.  
  228.     /**
  229.      * Clones this matrix. The elements are <strong>not</strong> cloned.
  230.      */
  231.     public synchronized Object clone() {
  232.         Matrix m = new Matrix();
  233.         m.rows = (Vector)rows.clone();
  234.  
  235.         return m;
  236.     }
  237.  
  238.     /**
  239.      * Empties the matrix.
  240.      */
  241.     public void removeAllElements() {
  242.         rows.removeAllElements();
  243.     }
  244.  
  245.     /**
  246.      * Adds an element to the matrix.
  247.      * @param r The row to add element.
  248.      * @param c The column to add element
  249.      * @param o The object to put in matrix
  250.      * @exception IllegalArgumentException Thrown if the element already exists in the matrix.
  251.      */
  252.     public synchronized void addElement(int r, int c, Object o) throws IllegalArgumentException {
  253.         ensureRowExists(r);
  254.  
  255.         //if does not contain row, add and return
  256.         MatrixElement elt = (MatrixElement)rows.elementAt(r);
  257.         if (elt == null) {
  258.             //row not in matrix so add
  259.             elt = new MatrixElement(c, o);
  260.             rows.setElementAt(elt, r);
  261.             return;
  262.         } else if (!elt.contains(c)) {
  263.             elt.set(c, o);
  264.  
  265.             return;
  266.         }
  267.  
  268.         //exception - should call update
  269.         throw new IllegalArgumentException("Element already in Matrix");
  270.     }
  271.  
  272.     /**
  273.      * Updates an existing element in the matrix. If the element is not already
  274.      * the matrix, it is added
  275.      * @param r The row to update element.
  276.      * @param c The column to update element
  277.      * @param o The object to put in matrix
  278.      */
  279.     public synchronized void updateElement(int r, int c, Object o) {
  280.         ensureRowExists(r);
  281.         //if does not contain row, add and return
  282.         MatrixElement elt = (MatrixElement)rows.elementAt(r);
  283.  
  284.         if (elt == null) {
  285.             //row not in matrix so add
  286.             elt = new MatrixElement(c, o);
  287.             rows.setElementAt(elt, r);
  288.             return;
  289.         } else {
  290.             elt.set(c, o);
  291.         }
  292.     }
  293.  
  294.    /**
  295.     * Determines if the matrix contains an element at the specified row.
  296.     * @param r The row to look for element.
  297.     */
  298.     public synchronized boolean containsRow(int r) {
  299.         if (rows.size()<=r) {
  300.             return false;
  301.         }
  302.  
  303.         //if does not contain row, add and return
  304.         MatrixElement elt = (MatrixElement)rows.elementAt(r);
  305.  
  306.         return elt!=null;
  307.     }
  308.  
  309.    /**
  310.     * Determines if the matrix contains an element at the specified location.
  311.     * @param r The row to look for element.
  312.     * @param c The column to look for element
  313.     */
  314.     public synchronized boolean contains(int r, int c) {
  315.         if (rows.size()<=r) {
  316.             return false;
  317.         }
  318.  
  319.         //if does not contain row, add and return
  320.         MatrixElement elt = (MatrixElement)rows.elementAt(r);
  321.  
  322.         if (elt == null) {
  323.             return false;
  324.         }
  325.  
  326.         return elt.contains(c);
  327.     }
  328.  
  329.    /**
  330.     * Determines if the matrix contains an element at the specified location.
  331.     * @param r The row to look for element.
  332.     * @param c The column to look for element
  333.     * @param o The element to look for at the location
  334.     */
  335.     public synchronized boolean contains(int r, int c, Object o) {
  336.         if (rows.size()<=r) {
  337.             return false;
  338.         }
  339.  
  340.         //if does not contain row, add and return
  341.         MatrixElement elt = (MatrixElement)rows.elementAt(r);
  342.  
  343.         if (elt == null) {
  344.             return false;
  345.         }
  346.  
  347.         return elt.contains(c, o);
  348.     }
  349.  
  350.     /**
  351.      * Method used by MatrixEnumation
  352.      */
  353.     MatrixElement firstRowElement(int r) {
  354.         return (MatrixElement)rows.elementAt(r);
  355.     }
  356.  
  357.    /**
  358.     * Gets an element at a specified location.
  359.     * @param r The row to look for element.
  360.     * @param c The column to look for element
  361.     * @return The element at the location
  362.     */
  363.     public synchronized Object elementAt(int r, int c) {
  364.         MatrixElement elt = (MatrixElement)rows.elementAt(r);
  365.  
  366.         //if does not contain row, add and return
  367.         if (elt == null) {
  368.             return null;
  369.         }
  370.  
  371.         return elt.objectAt(c);
  372.     }
  373.  
  374.    /**
  375.     * Removes an element at a specified location.
  376.     * @param r The row to look for element.
  377.     * @param c The column to look for element
  378.     */
  379.     public synchronized void removeElementAt(int r, int c) {
  380.         MatrixElement elt = (MatrixElement)rows.elementAt(r);
  381.  
  382.         //if does not contain row, add and return
  383.         if (elt == null) {
  384.             return;
  385.         }
  386.  
  387.         elt.unset(c);
  388.  
  389.         if (!elt.isValid()) {
  390.             rows.setElementAt(null, r);
  391.         }
  392.     }
  393.  
  394.     /**
  395.      * Adds row to the matrix. If the row already exists, that row and all
  396.      * subsequent rows are shifted down.
  397.      */
  398.     public synchronized void addRow(int r) {
  399.         if (rows.size() < r+1) {
  400.             //expand the vector to have a row 'r'
  401.             rows.setSize(r+1);
  402.             return;
  403.         }
  404.  
  405.         rows.insertElementAt(null, r);
  406.     }
  407.  
  408.    /**
  409.     * Removes a specified row from the matrix. Rows appearing after row will
  410.     * be shifted up.
  411.     * @param r The row to remove.
  412.     */
  413.     public void removeRow(int r) {
  414.         rows.removeElementAt(r);
  415.     }
  416.  
  417.     /**
  418.      * Copies a row from one matrix to another. Elements from this matrix
  419.      * are copied via a series of updateElement() calls.
  420.      * @param row The row to copy from this matrix
  421.      * @param toRow The row in the to matrix to put new elements.
  422.      * @param to The matrix to copy the row to.
  423.      */
  424.     public synchronized void copyRow(int row, int toRow, Matrix to) {
  425.         MatrixElement elt = (MatrixElement)rows.elementAt(row);
  426.  
  427.         //if does not contain row
  428.         if (elt == null) {
  429.             to.rows.setElementAt(null, toRow);
  430.         }
  431.  
  432.         to.ensureRowExists(toRow);
  433.         to.rows.setElementAt(elt.cloneRow(), toRow);
  434.     }
  435.  
  436.     /**
  437.      * Gets the number of rows in the matrix
  438.      */
  439.     public int rows() {
  440.         return rows.size();
  441.     }
  442.  
  443.     protected final void ensureRowExists(int r) {
  444.         if (rows.size() < r+1) {
  445.             rows.setSize(r+1);
  446.         }
  447.     }
  448.  
  449.     /**
  450.      * Gets an Enumberation to iterate the elements in the matrix.
  451.      */
  452.     public MatrixEnumeration elements() {
  453.         return new MatrixEnumeration(this);
  454.     }
  455.  
  456.     public String toString() {
  457.         return "Matrix: rows=" + rows();
  458.     }
  459.  
  460. /*   public static void main(String args[]) throws Exception {
  461.         Matrix m = new Matrix();
  462.         m.addElement(0, 0 , "0, 0");
  463.         m.addElement(0, 1, "0, 1");
  464.         m.addElement(2, 2, "2, 2");
  465.         m.addElement(2, 4, "2, 4");
  466.         m.addElement(5,3,"5, 3");
  467.  
  468.         System.out.println(m.elementAt(0, 0));
  469.         System.out.println(m.elementAt(0, 1));
  470.         System.out.println(m.elementAt(2, 4));
  471.         System.out.println(m.elementAt(5, 3));
  472.         m.removeElementAt(0,0);
  473.  
  474.         m.insertRow(2);
  475.         m.addElement(2,1,"new 2,1");
  476.  
  477.         System.out.println("Enumerating");
  478.         MatrixEnumeration e = m.elements();
  479.         while(e.hasMoreElements()) {
  480.             System.out.println(e.currRow() + " - " + e.nextElement());
  481.         }
  482.  
  483.         m.removeRow(2);
  484.         System.out.println("Enumerating");
  485.         e = m.elements();
  486.         while(e.hasMoreElements()) {
  487.             System.out.println(e.nextElement() + " - " + e.currRow() );
  488.         }
  489.         m.addElement(3, 3, "3, 3");
  490.         m.addElement(2, 2, "2, 2");
  491.         m.addElement(2, 0, "2, 0");
  492.         System.out.println("Enumerating");
  493.         e = m.elements();
  494.         System.out.println(e.advanceTo(2));
  495.         System.out.println(e.nextRow());
  496.         while(e.hasMoreElements()) {
  497.             System.out.println(e.nextElement() + " - " + e.currRow() );
  498.         }
  499.     }
  500. */
  501. }
  502.  
  503.  
  504.