package org.ovirt.engine.ui.uicommonweb.models.hosts; import java.util.List; public class AsyncIterator<T> { private List<T> source; private List<T> getSource() { return source; } private AsyncIteratorComplete<T> complete; public AsyncIteratorComplete<T> getComplete() { return complete; } public void setComplete(AsyncIteratorComplete<T> value) { complete = value; } private boolean stopped; public boolean getStopped() { return stopped; } public void setStopped(boolean value) { stopped = value; } private int counter; public int getCounter() { return counter; } public void setCounter(int value) { counter = value; } public AsyncIterator(List<T> source) { this.source = source; } public void iterate(AsyncIteratorFunc<T> func, AsyncIteratorPredicate<T> action) { setCounter(0); // Call complete method in case source is an empty list. if (getSource().isEmpty()) { if (getComplete() != null) { getComplete().run(null, null); } return; } for (T item : getSource()) { if (getStopped()) { break; } AsyncIteratorCallback<T> callback = new AsyncIteratorCallback<>(); callback.getNotifyEvent().addListener( (ev, sender, args) -> { CallbackContext<T> context = (CallbackContext<T>) ev.getContext(); AsyncIterator<T> iterator = context.getIterator(); AsyncIteratorPredicate<T> action1 = context.getAction(); T item1 = context.getItem(); Object value = args.getValue(); boolean callComplete = false; if (action1.match(item1, value)) { callComplete = true; iterator.setStopped(true); } // Call complete method even when there is no match. iterator.setCounter(iterator.getCounter() + 1); if (!iterator.getStopped() && iterator.getCounter() == iterator.getSource().size()) { callComplete = true; } // Call complete method. if (callComplete && iterator.getComplete() != null) { iterator.getComplete().run(item1, value); } }, new CallbackContext<>(this, item, action)); func.run(item, callback); } } private class CallbackContext<T> { private AsyncIterator<T> iterator; public AsyncIterator<T> getIterator() { return iterator; } private AsyncIteratorPredicate<T> action; public AsyncIteratorPredicate<T> getAction() { return action; } private T item; public T getItem() { return item; } private Object value; public Object getValue() { return value; } public void setValue(Object value) { this.value = value; } private CallbackContext(AsyncIterator<T> iterator, T item, AsyncIteratorPredicate<T> action) { this.iterator = iterator; this.item = item; this.action = action; } } }