001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    package org.apache.xbean.finder.util;
018    
019    import java.lang.reflect.Array;
020    import java.util.Collection;
021    import java.util.Iterator;
022    import java.util.List;
023    import java.util.ListIterator;
024    import java.util.NoSuchElementException;
025    
026    public class SingleLinkedList<E> implements List<E> {
027    
028        private Entry<E> entry;
029        private int size = 0;
030    
031        private class Entry<E> {
032    
033            private E value;
034            private Entry next;
035    
036            private Entry(E value, Entry next) {
037                this.value = value;
038                this.next = next;
039            }
040        }
041    
042    
043        public int size() {
044            return size;
045        }
046    
047        public boolean isEmpty() {
048            return size() == 0;
049        }
050    
051        public boolean contains(Object o) {
052            if (o == null) {
053                for (E e : this) {
054                    if (null == e) return true;
055                }
056            } else {
057                for (E e : this) {
058                    if (o.equals(e)) return true;
059                }
060            }
061    
062            return false;
063        }
064    
065        public Iterator<E> iterator() {
066            return values();
067        }
068    
069        public Object[] toArray() {
070            final Object[] array = new Object[size];
071            return toArray(array);
072        }
073    
074        public <T> T[] toArray(T[] a) {
075            if (a.length < size) a = (T[]) Array.newInstance(a.getClass().getComponentType(), size);
076            
077            Object[] array = a;
078            int i = 0;
079    
080            for (E e : this) {
081                array[i++] = e;
082            }
083            
084            return (T[]) array;
085        }
086    
087        public boolean add(E e) {
088            this.entry = new Entry(e, this.entry); 
089            size++;
090            return true;
091        }
092    
093        public boolean remove(Object o) {
094            throw new UnsupportedOperationException("remove");
095        }
096    
097        public boolean containsAll(Collection<?> c) {
098            throw new UnsupportedOperationException("containsAll");
099        }
100    
101        public boolean addAll(Collection<? extends E> c) {
102            throw new UnsupportedOperationException("addAll");
103        }
104    
105        public boolean addAll(int index, Collection<? extends E> c) {
106            throw new UnsupportedOperationException("addAll");
107        }
108    
109        public boolean removeAll(Collection<?> c) {
110            throw new UnsupportedOperationException("removeAll");
111        }
112    
113        public boolean retainAll(Collection<?> c) {
114            throw new UnsupportedOperationException("retainAll");
115        }
116    
117        public void clear() {
118            this.entry = null;
119            this.size = 0; 
120        }
121    
122        public E get(int index) {
123            bounds(index);
124            int i = size;
125            for (E e : this) {
126                if (--i == index) return e;
127            }
128    
129            throw new IllegalStateException("statement should not be reachable");
130        }
131    
132        public E set(int index, E element) {
133            bounds(index);
134            int i = size;
135    
136            for (Entry<E> entry : entries()) {
137                if (--i == index) {
138                    final E old = entry.value;
139                    entry.value = element;
140                    return old;
141                }
142            }
143    
144            throw new IllegalStateException("statement should not be reachable");
145        }
146    
147        public void add(int index, E element) {
148            throw new UnsupportedOperationException("add");
149        }
150    
151        public E remove(int index) {
152            throw new UnsupportedOperationException("remove");
153        }
154    
155        public int indexOf(Object o) {
156            throw new UnsupportedOperationException("indexOf");
157        }
158    
159        public int lastIndexOf(Object o) {
160            throw new UnsupportedOperationException("lastIndexOf");
161        }
162    
163        public ListIterator<E> listIterator() {
164            throw new UnsupportedOperationException("listIterator");
165        }
166    
167        public ListIterator<E> listIterator(int index) {
168            throw new UnsupportedOperationException("listIterator");
169        }
170    
171        public List<E> subList(int fromIndex, int toIndex) {
172            throw new UnsupportedOperationException("subList");
173        }
174    
175        private void bounds(int index) {
176            if (index >= size) throw new IndexOutOfBoundsException(index + " [size " + size + "]");
177            if (index < 0) throw new IndexOutOfBoundsException(index + " [size " + size + "]");
178        }
179    
180    
181        private Iterator<E> values() {
182            return new Values<E>(this.entry);
183        }
184    
185        private Entries entries() {
186            return new Entries(this.entry);
187        }
188        
189    
190        private class Values<E> implements Iterator<E> {
191    
192            private Entry<E> current;
193    
194            private Values(Entry<E> current) {
195                this.current = current;
196            }
197    
198            public boolean hasNext() {
199                return current != null;
200            }
201    
202            public E next() {
203                if (current == null) throw new NoSuchElementException();
204                
205                final E v = current.value;
206    
207                this.current = current.next;
208    
209                return v;
210            }
211    
212            public void remove() {
213                throw new UnsupportedOperationException("remove");
214            }
215        }
216    
217        private class Entries implements Iterator<Entry<E>>, Iterable<Entry<E>> {
218            private Entry<E> current;
219    
220            private Entries(Entry<E> current) {
221                this.current = current;
222            }
223    
224            public Iterator<Entry<E>> iterator() {
225                return this;
226            }
227    
228            public boolean hasNext() {
229                return current != null;
230            }
231    
232            public Entry<E> next() {
233                if (current == null) throw new NoSuchElementException();
234    
235                final Entry<E> value = this.current;
236    
237                this.current = current.next;
238    
239                return value;
240            }
241    
242            public void remove() {
243                throw new UnsupportedOperationException("remove");
244            }
245        }
246    }