/** * Copyright (C) 2010-2017 Structr GmbH * * This file is part of Structr <http://structr.org>. * * Structr is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * Structr is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Structr. If not, see <http://www.gnu.org/licenses/>. */ package org.structr.core.graph; import java.util.Iterator; import java.util.Set; import org.structr.common.Filter; import org.structr.common.SecurityContext; /** * An Iterable implementation that evaluates a set of predicates evaluate for * each element in the collection, deciding whether to include the element or * not. * * */ public class IterableFilter<T> implements Iterable<T> { private SecurityContext securityContext = null; private Iterator<T> sourceIterator = null; private Set<Filter<T>> filters = null; public IterableFilter(SecurityContext securityContext, Iterable<T> source, Set<Filter<T>> filters) { this.sourceIterator = source.iterator(); this.filters = filters; } @Override public Iterator<T> iterator() { return(new Iterator<T>() { private boolean hasNextCalled = false; private T currentElement = null; @Override public boolean hasNext() { do { if(sourceIterator.hasNext()) { currentElement = sourceIterator.next(); } else { currentElement = null; } } while(currentElement != null && !accept(securityContext, currentElement)); hasNextCalled = true; return(currentElement != null); } @Override public T next() { // prevent returning the same object over and over again // when user doesn't call hasNext() if(!hasNextCalled) { hasNext(); } else { hasNextCalled = false; } return(currentElement); } @Override public void remove() { throw new UnsupportedOperationException("IterableFilterIterator does not support removal of elements"); } }); } // ----- private methods ----- private boolean accept(SecurityContext securityContext, T element) { boolean ret = true; for(Filter<T> predicate : filters) { predicate.setSecurityContext(securityContext); ret &= predicate.accept(element); } return(ret); } }