blob: b70021fd2bab216b5cd751267be1054588b3f324 [file] [log] [blame]
/*
* 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();
}
}
}