| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. The ASF licenses this file to You |
| * under the Apache License, Version 2.0 (the "License"); you may not |
| * use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. For additional information regarding |
| * copyright in this work, please see the NOTICE file in the top level |
| * directory of this distribution. |
| */ |
| package org.apache.axiom.fom; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.ListIterator; |
| |
| /** |
| * Implements an ElementSet around an internal buffered iterator. Here's the rationale: Axiom parses incrementally. |
| * Using the iterators provided by Axiom, we can walk a set of elements while preserving the incremental parsing model, |
| * however, if we went with just java.util.Iterator, we'd lose the ability to do things like feed.getEntries().get(0), |
| * or use the new Java5 style iterators for (Entry e : feed.getEntries()). However, using a regular java.util.List also |
| * isn't a great option because it means we have to iterate through all of the elements before returning back to the |
| * caller. This gives us a hybrid approach. We create an internal iterator, then create a List from that, the iterator |
| * is consumed as the list is used. The List itself is unmodifiable. |
| */ |
| public class FOMList<T> extends java.util.AbstractCollection<T> implements List<T> { |
| |
| private final Iterator<? extends T> i; |
| private final List<T> buffer = new ArrayList<T>(); |
| |
| public FOMList(Iterator<? extends T> i) { |
| this.i = i; |
| } |
| |
| public List<T> getAsList() { |
| buffer(-1); |
| return java.util.Collections.unmodifiableList(buffer); |
| } |
| |
| private boolean finished() { |
| return !i.hasNext(); |
| } |
| |
| private int buffered() { |
| return buffer.size() - 1; |
| } |
| |
| private int buffer(int n) { |
| if (i.hasNext()) { |
| int read = 0; |
| while (i.hasNext() && (read++ < n || n == -1)) { |
| buffer.add(i.next()); |
| } |
| } |
| return buffered(); |
| } |
| |
| public T get(int index) { |
| int n = buffered(); |
| if (index > n && (index > buffer(index - n))) |
| throw new ArrayIndexOutOfBoundsException(index); |
| return (T)buffer.get(index); |
| } |
| |
| public int size() { |
| return buffer(-1) + 1; |
| } |
| |
| public Iterator<T> iterator() { |
| return new BufferIterator<T>(this); |
| } |
| |
| private Iterator<T> iterator(int index) { |
| return new BufferIterator<T>(this, index); |
| } |
| |
| public boolean add(T o) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public void add(int index, T element) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public boolean addAll(Collection<? extends T> c) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public boolean addAll(int index, Collection<? extends T> c) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public void clear() { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public boolean contains(Object o) { |
| buffer(-1); |
| return buffer.contains(o); |
| } |
| |
| public boolean containsAll(Collection<?> c) { |
| for (Object o : c) |
| if (contains(o)) |
| return true; |
| return false; |
| } |
| |
| public int indexOf(Object o) { |
| buffer(-1); |
| return buffer.indexOf(o); |
| } |
| |
| public boolean isEmpty() { |
| buffer(-1); |
| return buffer.isEmpty(); |
| } |
| |
| public int lastIndexOf(Object o) { |
| buffer(-1); |
| return buffer.lastIndexOf(o); |
| } |
| |
| public ListIterator<T> listIterator() { |
| return (ListIterator<T>)iterator(); |
| } |
| |
| public ListIterator<T> listIterator(int index) { |
| return (ListIterator<T>)iterator(index); |
| } |
| |
| public boolean remove(Object o) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public T remove(int index) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public boolean removeAll(Collection<?> c) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public boolean retainAll(Collection<?> c) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public T set(int index, T element) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public List<T> subList(int fromIndex, int toIndex) { |
| buffer(-1); |
| return Collections.unmodifiableList(buffer.subList(fromIndex, toIndex)); |
| } |
| |
| public Object[] toArray() { |
| buffer(-1); |
| return buffer.toArray(); |
| } |
| |
| public <U> U[] toArray(U[] a) { |
| buffer(-1); |
| return buffer.toArray(a); |
| } |
| |
| private class BufferIterator<M> implements ListIterator<M> { |
| |
| private FOMList<M> set = null; |
| private int counter = 0; |
| |
| BufferIterator(FOMList<M> set) { |
| this.set = set; |
| } |
| |
| BufferIterator(FOMList<M> set, int index) { |
| this.set = set; |
| this.counter = index; |
| } |
| |
| public boolean hasNext() { |
| return (!set.finished()) || (set.finished() && counter < buffer.size()); |
| } |
| |
| public M next() { |
| return (M)set.get(counter++); |
| } |
| |
| public void remove() { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public void add(M o) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public boolean hasPrevious() { |
| return counter > 0; |
| } |
| |
| public int nextIndex() { |
| if (hasNext()) |
| return counter + 1; |
| else |
| return buffer.size(); |
| } |
| |
| public M previous() { |
| return (M)set.get(--counter); |
| } |
| |
| public int previousIndex() { |
| if (hasPrevious()) |
| return counter - 1; |
| else |
| return -1; |
| } |
| |
| public void set(M o) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| } |
| } |