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 }