001    package listFW.factory;
002    
003    import listFW.*;
004    import listFW.visitor.*;
005    
006    /**
007     * Manufactures concrete IMTList<E> and INEList<E> objects.  
008     * The INEList object is implemented as a private anonymous inner object.
009     * The implementations for MTList and NEList are 
010     * completely invisible to the outside of this factory.
011     * @author Dung X. Nguyen and Stephen Wong
012     * @since Copyright 2004 by SBW & DXN - All rights reserved
013     * @author Mathias Ricken - Copyright 2008 - All rights reserved.
014     */
015    public class CompositeListFactory<E> implements IListFactory<E> {
016        
017        /**
018         * Note: A parametrized IMTList(E> cannot be static.
019         */
020        private final IMTList<E> mtList = new IMTList<E>() {
021            final public <R,P>  R execute(IListAlgo<? super E , R, P> algo, P ... inp) {
022                return algo.emptyCase(this, inp);
023            }
024            
025            public String toString() {
026                return toStringAlgo.emptyCase(this);
027            }
028        };
029        
030        private static final IListAlgo<Object, String, ?> toStringAlgo = ToStringAlgo.Singleton;
031        
032        /**
033         * Creates an empty list.
034         * @return an IMTList object.
035         */
036        public IMTList<E> makeEmptyList() {
037            return mtList;
038        }
039        
040        /**
041         * Creates a non-empty list containing a given first and a given rest.
042         * @param first a data object.
043         * @param rest != null, the rest of the non-empty list to be manufactured.
044         * @return an INEList object containing first and rest
045         */
046        public INEList<E> makeNEList(final E first, final IList<? extends E> rest) {
047            return new INEList<E>(){
048                final public E getFirst() {
049                    return first;
050                }
051                
052                final public IList<? extends E> getRest() {
053                    return rest;
054                }
055                
056                final public <R,P> R execute(IListAlgo<? super E, R , P> algo, P ... inp) {
057                    return algo.nonEmptyCase(this, inp);
058                }
059                
060                public String toString() {
061                    return toStringAlgo.nonEmptyCase(this);
062                }
063            };
064        }
065    }