package org.infinispan.jcache; import java.util.Iterator; import java.util.NoSuchElementException; import javax.cache.event.CacheEntryEvent; import javax.cache.event.CacheEntryEventFilter; /** * A adapter to {@link Iterator}s to allow filtering of {@link CacheEntryEvent}s * * @author Galder ZamarreƱo * @param <K> the type of keys * @param <V> the type of value * @see Class based on the JSR-107 reference implementation (RI) of * {@link Iterator<CacheEntryEvent<? extends K, ? extends V>>} */ public class JCacheEventFilteringIterator<K, V> implements Iterator<CacheEntryEvent<? extends K, ? extends V>> { /** * The underlying iterator to filter. */ private Iterator<CacheEntryEvent<? extends K, ? extends V>> iterator; /** * The filter to apply to Cache Entry Events in the {@link Iterator}. */ private CacheEntryEventFilter<? super K, ? super V> filter; /** * The next available Cache Entry Event that satisfies the filter. * (when null we must seek to find the next event) */ private CacheEntryEvent<? extends K, ? extends V> nextEntry; /** * Constructs an {@link JCacheEventFilteringIterator}. * * @param iterator the underlying iterator to filter * @param filter the filter to apply to entries in the iterator */ public JCacheEventFilteringIterator( Iterator<CacheEntryEvent<? extends K, ? extends V>> iterator, CacheEntryEventFilter<? super K, ? super V> filter) { this.iterator = iterator; this.filter = filter; this.nextEntry = null; } /** * Fetches the next available, entry that satisfies the filter from * the underlying iterator */ private void fetch() { while (nextEntry == null && iterator.hasNext()) { CacheEntryEvent<? extends K, ? extends V> entry = iterator.next(); if (filter.evaluate(entry)) { nextEntry = entry; } } } /** * {@inheritDoc} */ @Override public boolean hasNext() { if (nextEntry == null) { fetch(); } return nextEntry != null; } /** * {@inheritDoc} */ @Override public CacheEntryEvent<? extends K, ? extends V> next() { if (hasNext()) { CacheEntryEvent<? extends K, ? extends V> entry = nextEntry; //reset nextEntry to force fetching the next available entry nextEntry = null; return entry; } else { throw new NoSuchElementException(); } } /** * {@inheritDoc} */ @Override public void remove() { iterator.remove(); nextEntry = null; } }