001    package lrs;
002    
003    /**
004     * Mutable linear recursive structure.
005     <pre>
006     * Visitor Pattern: Serves as a host capable of executing algorithms which are
007     * visitors.
008     </pre>
009     * @author Dung X. Nguyen and Stephen Wong  Copyright 2005 - All rights reserved.
010     * @since 8/25/05
011     */
012    public class LRStruct {
013      /**
014       * The state of of this <code>LRStruct</code>.
015       */
016      private ANode _head;
017      
018      /**
019       * Initializes this <code>LRStruct</code> to the empty state.
020       */
021      public LRStruct() {
022        _head = EmptyNode.Singleton;
023      }
024      
025      /**
026       * Returns "()" if empty, otherwise returns the contents of this
027       * <code>LRStruct</code> enclosed in parentheses.
028       */
029      public String toString()  {
030        return _head.toString(this);
031      }
032      
033      /**
034       * Inserts dat to the front of this LRStruct.<br>
035       * post condition: <code>getFirst()</code> now returns dat.
036       * @param dat data to be inserted.
037       * @return this <code>LRStruct</code>
038       */
039      public final LRStruct insertFront(Object dat) {
040        return _head.insertFront(dat, this);
041      }
042      
043      /**
044       * Removes and returns this <code>LRStruct</code>'s first.
045       */
046      public final Object removeFront() {
047        return _head.removeFront(this);
048      }
049      
050      /**
051       * Gets the first data element from this <code>LRStruct</code>
052       */
053      public final Object getFirst() {
054        return _head.getFirst (this);
055      }
056      
057      /**
058       * Sets first data element to a new value.
059       * @param dat replaces the existing first for this <code>LRStruct</code>.
060       * @throws NoSuchElementException if this <code>LRStruct</code> is empty.
061       * @return this <code>LRStruct</code>
062       */
063      public final LRStruct setFirst(Object dat) {
064        return _head.setFirst (dat, this);
065      }
066      
067      /**
068       * Gets the rest of this <code>LRStruct</code>.
069       * @throws NoSuchElementException if this <code>LRStruct</code> is empty.
070       */
071      public final LRStruct getRest() {
072        return _head.getRest(this);
073      }
074      
075      /**
076       * Sets a new tail for this <code>LRStruct</code>.<br>
077       * post condition: <code>getRest()</code> now returns tail.
078       * @throws NoSuchElementException if this <code>LRStruct</code> is empty.
079       * @return this <code>LRStruct</code>
080       */
081      public final LRStruct setRest(LRStruct tail) {
082        return _head.setRest(tail, this);
083      }
084      
085      /**
086       * Hook method to execute an algorithm with a given input and return
087       * an appropriate output object.
088       * @param algo an algorithm (!= null) that operates on this LRStruct.
089       * @param inp input variable argument list of objects needed by visitor algo.
090       * @return output object resulting from the execution of algo.
091       */
092      public final Object execute(IAlgo algo, Object... inp) {
093        return _head.execute(this, algo, inp);
094      }
095      
096      /* Package access only: */
097      
098      /**
099       * Initiazes this <code>LRStruct</code> with a given head node.
100       * @param node != null.
101       */
102      LRStruct(ANode node)  {
103        _head = node;
104      }
105      
106      /**
107       * Changes the head node (i.e. state) of this <code>LRStruct</code>.
108       * @param head replaces the exisiting state of this <code>LRStruct</code>.
109       * @return this <code>LRStruct</code>
110       */
111      final LRStruct setHead (ANode head) {
112        _head = head;
113        return this;
114      }
115      
116      /**
117       * Gets the head node (i.e. state) of this <code>LRStruct</code>.
118       * @return the head node.
119       */
120      final ANode getHead () {
121        return _head;
122      }
123    }
124