package er.neo4jadaptor.query.neo4j_eval; import org.neo4j.graphdb.PropertyContainer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.webobjects.eoaccess.EOEntity; import com.webobjects.eocontrol.EOQualifier; import er.neo4jadaptor.query.Results; import er.neo4jadaptor.query.neo4j_eval.evaluators.Evaluator; import er.neo4jadaptor.utils.cursor.Cursor; /** * Filter that using Neo4J java api examines node/relationship properties and their relationships * to filter those that exactly match search criteria. * * @author Jedrzej Sobanski * * @param <T> */ public class EvaluatingFilter<T extends PropertyContainer> implements Results<T> { private static final Logger log = LoggerFactory.getLogger(EvaluatingFilter.class); @SuppressWarnings("unchecked") private static final EvaluationQueryConverter<?> generator = new EvaluationQueryConverter(); private T next; private Cursor<T> it; private boolean hasFinished = false; private final Results<T> wrapped; private final Evaluator<T> eval; private int countHits = 0; private int countMisses = 0; @SuppressWarnings("unchecked") public EvaluatingFilter(Results<T> objects, EOEntity entity, EOQualifier q) { this(objects, (Evaluator<T>) generator.fullQuery(entity, q)); } private EvaluatingFilter(Results<T> wrapped, Evaluator<T> eval) { this.wrapped = wrapped; this.eval = eval; this.it = wrapped; } public boolean hasNext() { if (hasFinished) { return false; } else if (next == null) { next = calculateNext(); if (next == null) { hasFinished = true; } } return next != null; } public void close() { it.close(); } public T next() { T result = next; next = null; return result; } private T calculateNext() { while (it.hasNext()) { T candidate = it.next(); if (eval.evaluate(candidate)) { countHits++; log.debug("Evaluating {} with {}, result: match", candidate, eval); return candidate; } else { countMisses++; log.debug("Evaluating {} with {}, result: miss", candidate, eval); } } if (log.isDebugEnabled() && countMisses > 0) { log.debug("Had {} hits vs. {} misses for {}", countHits, countMisses, wrapped); } return null; } public void remove() { throw new UnsupportedOperationException(); } }