package de.renew.util;

import java.util.Enumeration;

/**
 * Custom class implementing the Enumeration interface. Checks if a provided Object is capable of
 * providing enumerator outputs.
 */
public class ClassCheckEnumeration implements Enumeration<Object> {
    /**
     * An Object-extending object which implements the enumeration interface. This object will be tested for
     * enumeration capabilities.
     */
    private final Enumeration<?> _source;
    /**
     * A Class against which will be verified that the Enumerator-returned output is of this class
     */
    private final Class<?> _clazz;
    /**
     * Stores the output of the Enumerator call
     */
    private Object _next = null;
    /**
     * boolean used by the nextElement method to quit the while-loop querying the enumerator for its outputs
     */
    private boolean _more = true;

    /**
     * For a given Object, check if it has enumeration capabilities.
     *
     * @param source the Object on which one can call enumerator methods
     * @param clazz the Class whose type objects returned by the enumeration should be
     */
    public ClassCheckEnumeration(Enumeration<?> source, Class<?> clazz) {
        this._source = source;
        this._clazz = clazz;
        nextElement();
    }

    @Override
    public boolean hasMoreElements() {
        return _more;
    }

    /**
     * Verify that the class is capable of enumeration and produces objects of the type set during construction.
     * Terminates when the enumeration produces no more elements or of a different class than submitted.
     *
     * @return the output of the last performed enumerator call, before any class checking has occurred.
     */
    @Override
    public synchronized Object nextElement() {
        Object result = _next;
        _more = false;
        while (_source.hasMoreElements() && !_more) {
            _next = _source.nextElement();
            _more = _clazz.isInstance(_next);
        }
        return result;
    }
}