org.codefilarete.tool.bean.InheritedElementIterator Maven / Gradle / Ivy
package org.codefilarete.tool.bean;
import java.util.Collections;
import java.util.Iterator;
import java.util.NoSuchElementException;
import org.codefilarete.tool.collection.ArrayIterator;
import org.codefilarete.tool.collection.ReadOnlyIterator;
/**
* An {@link java.util.Iterator} that gets its informations from each class of a hierarchy.
*
* @author Guillaume Mary
*/
public abstract class InheritedElementIterator extends ReadOnlyIterator {
protected Iterator classIterator;
protected Iterator inheritedElementIterator = Collections.emptyIterator();
public InheritedElementIterator(Class aClass) {
this(new ClassIterator(aClass));
}
public InheritedElementIterator(Iterator classIterator) {
this.classIterator = classIterator;
}
@Override
public boolean hasNext() {
// simple case
if (inheritedElementIterator.hasNext()) {
return true;
} else {
// no more element for the current iterator => we must scan upper classes if they have some
while (classIterator.hasNext() && !inheritedElementIterator.hasNext()) {
// transforming the class elements to an Iterator
inheritedElementIterator = nextInheritedElementIterator(classIterator.next());
}
return inheritedElementIterator.hasNext();
}
}
protected Iterator nextInheritedElementIterator(Class clazz) {
return new ArrayIterator<>(getElements(clazz));
}
@Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return inheritedElementIterator.next();
}
/**
* Gives any element from a class: field, method, interface, ...
*
* @param clazz the class for which elements must be given
* @return an array of element, not null
*/
protected abstract T[] getElements(Class clazz);
}