package com.tinkerpop.blueprints.util; import com.tinkerpop.blueprints.CloseableIterable; import com.tinkerpop.blueprints.Compare; import com.tinkerpop.blueprints.Edge; import com.tinkerpop.blueprints.Element; import com.tinkerpop.blueprints.Predicate; import java.util.Iterator; import java.util.NoSuchElementException; /** * This is a helper class for filtering an iterable of elements by their key/value. * Useful for graph implementations that do no support automatic key indices and need to filter on Graph.getVertices/Edges(key,value). * * @author Marko A. Rodriguez (http://markorodriguez.com) */ public class PropertyFilteredIterable<T extends Element> implements CloseableIterable<T> { private final Iterable<T> iterable; private final HasContainer hasContainer; public PropertyFilteredIterable(final String key, final Object value, final Iterable<T> iterable) { this.iterable = iterable; this.hasContainer = new HasContainer(key, Compare.EQUAL, value); } public void close() { if (this.iterable instanceof CloseableIterable) { ((CloseableIterable) this.iterable).close(); } } public Iterator<T> iterator() { return new Iterator<T>() { private Iterator<T> itty = iterable.iterator(); private T nextElement = null; public void remove() { this.itty.remove(); } public boolean hasNext() { if (null != nextElement) return true; else { try { while (true) { final T element = this.itty.next(); if (hasContainer.isLegal(element)) { this.nextElement = element; return true; } } } catch (NoSuchElementException e) { this.nextElement = null; return false; } } } public T next() { if (null != this.nextElement) { final T temp = this.nextElement; this.nextElement = null; return temp; } else { while (true) { final T element = this.itty.next(); if (hasContainer.isLegal(element)) return element; } } } }; } protected class HasContainer { public String key; public Object value; public Predicate predicate; public HasContainer(final String key, final Predicate predicate, final Object value) { this.key = key; this.value = value; this.predicate = predicate; } public boolean isLegal(final Element element) { if (this.key.equals(StringFactory.ID)) { return this.predicate.evaluate(element.getId(), this.value); } else if (this.key.equals(StringFactory.LABEL) && element instanceof Edge) { return this.predicate.evaluate(((Edge) element).getLabel(), this.value); } else { return this.predicate.evaluate(element.getProperty(this.key), this.value); } } } }