001 package rac;
002
003 import listFW.*;
004 import listFW.factory.*;
005 import lrs.*;
006
007 /**
008 * Implements a factory for restricted access containers. These
009 * restricted access containers are implemented using an LRStruct to
010 * hold the data objects.
011 * @author Mathias Ricken - Copyright 2008 - All rights reserved.
012 */
013 public abstract class ALRSRACFactory<T> implements IRACFactory<T> {
014 /**
015 * Implements a general-purpose restricted access container using
016 * an LRStruct. How?
017 *
018 * The next item to remove is always at the front of the list of
019 * contained objects. This is invariant!
020 *
021 * Insertion is, however, delegated to a strategy routine; and
022 * this strategy is provided to the container. This strategy
023 * varies to implement the desired kind of container, e.g., queue
024 * vs. stack.
025 *
026 * This inner class is protected so that classes derived from its
027 * factory can reuse it to create other kinds of restricted access
028 * container.
029 */
030 protected class LRSRAContainer<T> implements IRAContainer<T> {
031 private IAlgo<T,LRStruct<T>,T> _insertStrategy;
032 private LRStruct<T> _lrs;
033
034 public LRSRAContainer(IAlgo<T,LRStruct<T>,T> strategy) {
035 _insertStrategy = strategy;
036 _lrs = new LRStruct<T>();
037 }
038
039 /**
040 * Empty the container.
041 */
042 public void clear() {
043 _lrs = new LRStruct<T>();
044 }
045
046 /**
047 * Return TRUE if the container is full; otherwise, return
048 * FALSE.
049 *
050 * This implementation can hold an arbitrary number of
051 * objects. Thus, always return false.
052 */
053 public boolean isFull() {
054 return false;
055 }
056
057 /**
058 * Return an immutable list of all elements in the container.
059 */
060 public IList<T> elements(final IListFactory<T> fact) {
061 return _lrs.execute(new IAlgo<T,IList<T>,Void>() {
062 public IList<T> emptyCase(LRStruct<T> host, Void... input) {
063 return fact.makeEmptyList();
064 }
065
066 public IList<T> nonEmptyCase(LRStruct<T> host, Void... input) {
067 return fact.makeNEList(host.getFirst(),
068 host.getRest().execute(this, input));
069 }
070 });
071 }
072
073 /**
074 * Remove the next item from the container and return it.
075 */
076 public T get() {
077 return _lrs.removeFront();
078 }
079
080 /**
081 * Add an item to the container.
082 */
083 @SuppressWarnings("unchecked")
084 public void put(T input) {
085 _lrs.execute(_insertStrategy, input);
086 }
087
088 /**
089 * Return the next element in this IRAContainer withour removing it.
090 * @throw an Exception if this IRAContainer is empty.
091 */
092 public T peek() {
093 return _lrs.getFirst();
094 }
095
096 /**
097 * Extensibility hook to accept a visitor algorithm.
098 * @param v The visitor to execute
099 * @param inp An arbitrary input parameter for the visitor
100 * @return The return value of the calculation performed by the visitor.
101 */
102 public <R,P> R execute(final IRACVisitor<T,R,P> v, P... inp) {
103 return _lrs.execute(new IAlgo<T,R,P>() {
104 public R emptyCase(LRStruct<T> host, P... i) {
105 return v.emptyCase(LRSRAContainer.this, i);
106 }
107 public R nonEmptyCase(LRStruct<T> host, P... i) {
108 return v.nonEmptyCase(LRSRAContainer.this, i);
109 }
110 }, inp);
111 }
112
113 }
114 }
115