home *** CD-ROM | disk | FTP | other *** search
/ Java Programmer's Toolkit / Java Programmer's Toolkit.iso / applets / collectn / incrmap.jav < prev    next >
Encoding:
Text File  |  1995-12-14  |  7.3 KB  |  283 lines

  1. /*
  2.   File: IncrMap.java
  3.  
  4.   Originally written by Doug Lea and released into the public domain. 
  5.   Thanks for the assistance and support of Sun Microsystems Labs, Agorics 
  6.   Inc, Loral, and everyone contributing, testing, and using this code.
  7.  
  8.   History:
  9.   Date     Who                What
  10.   24Sep95  dl@cs.oswego.edu   Create from collections.java  working file
  11.   13Oct95  dl                 Changed to use accessOnly
  12.  
  13. */
  14.   
  15. package collections;
  16.  
  17. import java.util.Enumeration;
  18. import java.util.NoSuchElementException;
  19.  
  20. /**
  21.  *
  22.  *
  23.  * Implementation of Immutable Map
  24.  * @author Doug Lea
  25.  * @version 0.93
  26.  *
  27.  * <P> For an introduction to this package see <A HREF="index.html"> Overview </A>.
  28. **/
  29.  
  30. public final class IncrMap extends IncrImpl implements Map {
  31.  
  32. /**
  33.  * Make a new pure map using the default underlying Map implementation
  34. **/
  35.   public IncrMap() { this(DefaultImplementations.map()); }
  36.  
  37. /**
  38.  * Make a pure map managing the given updatable map s.
  39.  * Warning: Do not modify s during the the lifetime of the constructed pure map!
  40. **/
  41.   public IncrMap(UpdatableMap s) { super(s); }
  42.  
  43.  
  44. /**
  45.  * Make a copy. Uses lazy update.
  46. **/
  47.  
  48.   protected Object clone() throws CloneNotSupportedException {
  49.     undelta();
  50.     IncrMap s = new IncrMap((UpdatableMap)(updatable_));
  51.     nextVersion_ = s;
  52.     updatable_ = null;
  53.     op_ = NO_EDIT;
  54.     return s;
  55.   }
  56.  
  57. /**
  58.  * Implements collections.Map.canIncludeKey.
  59.  * @see collections.Map#canIncludeKey
  60. **/
  61.   public boolean canIncludeKey(Object key) {
  62.     return ((UpdatableMap)accessOnly()).canIncludeKey(key);
  63.   }
  64.  
  65.  
  66. /**
  67.  * Implements collections.Map.includesKey.
  68.  * @see collections.Map#includesKey
  69. **/
  70.   public synchronized boolean     includesKey(Object key) {
  71.     return ((UpdatableMap)accessOnly()).includesKey(key);
  72.   }
  73.  
  74. /**
  75.  * Implements collections.Map.includesAt.
  76.  * @see collections.Map#includesAt
  77. **/
  78.   public synchronized boolean     includesAt(Object key, Object value) {
  79.     return ((UpdatableMap)accessOnly()).includesAt(key, value);
  80.   }
  81.  
  82. /**
  83.  * Implements collections.Map.at.
  84.  * @see collections.Map#at
  85. **/
  86.   public synchronized Object      at(Object key) 
  87.   throws  NoSuchElementException {
  88.     return ((UpdatableMap)accessOnly()).at(key);
  89.   }
  90.  
  91. /**
  92.  * Implements collections.Map.aKeyOf.
  93.  * @see collections.Map#aKeyOf
  94. **/
  95.   public synchronized Object aKeyOf(Object element) {
  96.     return ((UpdatableMap)accessOnly()).aKeyOf(element);
  97.   }
  98.  
  99.  
  100. /**
  101.  * Implements collections.Map.keys.
  102.  * @see collections.Map#keys
  103. **/
  104.   public synchronized CollectionEnumeration keys() {
  105.     undelta(); 
  106.     // wrap the underlying enumeration in Incr version 
  107.     CollectionEnumeration e = ((UpdatableMap)(updatable_)).keys();
  108.     IncrCollectionEnumeration ie = new IncrCollectionEnumeration(this, e);
  109.     pin(ie);
  110.     return ie;
  111.   }
  112.  
  113.  
  114.  
  115. /**
  116.  * Implements collections.Map.puttingAt.
  117.  * @see collections.Map#puttingAt
  118. **/
  119.   public synchronized /* IncrMap */ Map  puttingAt(Object key, Object element) 
  120.   throws IllegalElementException {
  121.     undelta(); 
  122.     UpdatableMap u = (UpdatableMap)updatable_;
  123.     boolean has = u.includesAt(key, element);
  124.     if (has) 
  125.       return this;
  126.     else { // if already has key, undo via another include
  127.       boolean hasKey = u.includesKey(key);
  128.       if (hasKey) {
  129.         try {
  130.           secondObjectArg_ = u.at(key);
  131.         }
  132.         catch (NoSuchElementException ex) {}
  133.         u.putAt(key, element);
  134.         IncrMap s = new IncrMap(u);
  135.         nextVersion_ = s;
  136.         updatable_ = null;
  137.         firstObjectArg_ = key;
  138.         op_ = ADD_EDIT;
  139.         return s;
  140.       }
  141.       else {
  142.         u.putAt(key, element);
  143.         IncrMap s = new IncrMap(u);
  144.         nextVersion_ = s;
  145.         updatable_ = null;
  146.         firstObjectArg_ = key;
  147.         op_ = REMOVE_EDIT;
  148.         return s;
  149.       }
  150.     }
  151.   }
  152.  
  153. /**
  154.  * Implements collections.Map.removingAt
  155.  * @see collections.Map#removingAt
  156. **/
  157.   public synchronized /* IncrMap */ Map   removingAt(Object key) {
  158.     undelta(); 
  159.     UpdatableMap u = (UpdatableMap)updatable_;
  160.     boolean has = u.includesKey(key);
  161.     if (has) 
  162.       return this;
  163.     else {
  164.       try {
  165.         secondObjectArg_ = u.at(key);
  166.       }
  167.       catch (NoSuchElementException ex) {}
  168.       u.removeAt(key);
  169.       IncrMap s = new IncrMap(u);
  170.       nextVersion_ = s;
  171.       updatable_ = null;
  172.       firstObjectArg_ = key;
  173.       op_ = ADD_EDIT;
  174.       return s;
  175.     }
  176.   }
  177.  
  178.  
  179. /**
  180.  * Implements collections.Collection.removingOneOf
  181.  * @see collections.Collection#removingOneOf
  182. **/
  183.   public synchronized /* IncrMap */ Collection  removingOneOf(Object element) {
  184.     undelta(); 
  185.     UpdatableMap u = (UpdatableMap)updatable_;
  186.     Object key = u.aKeyOf(element);
  187.     if (key == null)
  188.       return this;
  189.     else {
  190.       u.removeAt(key);
  191.       IncrMap s = new IncrMap(u);
  192.       nextVersion_ = s;
  193.       updatable_ = null;
  194.       firstObjectArg_ = key;
  195.       secondObjectArg_ = element;
  196.       op_ = ADD_EDIT;
  197.       return s;
  198.     }
  199.   }
  200.  
  201.  
  202. /**
  203.  * Implements collections.Collection.excluding.
  204.  * If more than one occurrence of element exists, it makes
  205.  * a full, non-lazy copy.
  206.  * @see collections.Collection#excluding
  207. **/
  208.   public synchronized /* IncrMap */ Collection  excluding(Object element) {
  209.     undelta(); 
  210.     UpdatableMap u = (UpdatableMap)updatable_;
  211.     int occ = u.occurrencesOf(element);
  212.     if (occ == 0)
  213.       return this;
  214.     else if (occ == 1)
  215.       return this.removingOneOf(element);
  216.     else {
  217.       UpdatableMap c = (UpdatableMap)(u.duplicate());
  218.       c.exclude(element);
  219.       return new IncrMap(c);
  220.     }
  221.   }
  222.  
  223.  
  224. /**
  225.  * Implements collections.Collection.replacingAllOf
  226.  * If more than one occurrence of element exists, it makes
  227.  * a full, non-lazy copy.
  228.  * @see collections.Collection#replacingAllOf
  229. **/
  230.   public synchronized /* IncrMap */ Collection  replacingAllOf(Object oldElement,
  231.                                              Object newElement) 
  232.   throws IllegalElementException {
  233.     undelta(); 
  234.     UpdatableMap u = (UpdatableMap)updatable_;
  235.     int oldocc = u.occurrencesOf(oldElement);
  236.     if (oldocc == 0)
  237.       return this;
  238.     else if (oldocc == 1)
  239.       return this.replacingOneOf(oldElement, newElement);
  240.     else {
  241.       UpdatableMap c = (UpdatableMap)(u.duplicate());
  242.       c.replaceAllOf(oldElement, newElement);
  243.       return new IncrMap(c);
  244.     }
  245.   }
  246.  
  247. /**
  248.  * Implements collections.Collection.replacingOneOf
  249.  * @see collections.Collection#replacingOneOf
  250. **/
  251.   public synchronized /* IncrMap */ Collection replacingOneOf(Object oldElement,
  252.                                                     Object newElement) 
  253.   throws IllegalElementException {
  254.     undelta(); 
  255.     UpdatableMap u = (UpdatableMap)updatable_;
  256.     Object key = u.aKeyOf(oldElement);
  257.     if (key == null)
  258.       return this;
  259.     else
  260.       return this.puttingAt(key, newElement);
  261.   }
  262.  
  263.  
  264. /**
  265.  * Perform updates within an edit chain
  266. **/
  267.   protected synchronized UpdatableCollection doEdit(UpdatableCollection c) { 
  268.     UpdatableMap u = (UpdatableMap)c;
  269.     try { 
  270.       if (op_ == ADD_EDIT) 
  271.         u.putAt(firstObjectArg_, secondObjectArg_);
  272.       else if (op_ == REMOVE_EDIT)
  273.         u.removeAt(firstObjectArg_);
  274.     }
  275.     catch (IllegalElementException ex) {} // we've screened for all possible
  276.     return u;
  277.   }
  278.  
  279.  
  280. }
  281.  
  282.  
  283.