/*
* This file is part of the HyperGraphDB source distribution. This is copyrighted
* software. For permitted uses, licensing options and redistribution, please see
* the LicensingInformation file at the root level of the distribution.
*
* Copyright (c) 2005-2010 Kobrix Software, Inc. All rights reserved.
*/
package org.hypergraphdb.query.impl;
import org.hypergraphdb.HGRandomAccessResult;
import org.hypergraphdb.HyperGraph;
import org.hypergraphdb.HGQuery;
import org.hypergraphdb.HGHandle;
import org.hypergraphdb.HGSearchResult;
import org.hypergraphdb.query.HGAtomPredicate;
import org.hypergraphdb.util.HGUtils;
import org.hypergraphdb.util.Mapping;
/**
* <p>
* A <code>HGQuery</code> whose result is constructed by filtering the result set
* of another <code>HGQuery</code> according to a <code>HGQueryCondition</code>.
* </p>
*
* @author Borislav Iordanov
*/
public final class PredicateBasedRAFilter<T> extends HGQuery<T>
{
private HGQuery<T> query;
private Mapping<T, Boolean> predicate;
/**
* <p>Construct a <code>PredicateBasedFilter</code>, filtering the result
* set of a given query based on a <code>HGQueryCondition</code>.
* </p>
*
* @param query The base query that is being filtered.
* @param predicate The filtering predicate.
*/
public PredicateBasedRAFilter(final HyperGraph graph,
final HGQuery<T> query,
final HGAtomPredicate atomPredicate)
{
this.graph = graph;
this.query = query;
this.predicate = new Mapping<T, Boolean>() {
public Boolean eval(T h)
{
return atomPredicate.satisfies(graph, (HGHandle)h);
}
};
}
public PredicateBasedRAFilter(final HyperGraph graph,
final HGQuery<T> query,
final Mapping<T, Boolean> predicate)
{
this.graph = graph;
this.query = query;
this.predicate = predicate;
}
@SuppressWarnings("unchecked")
public HGSearchResult<T> execute()
{
HGRandomAccessResult<T> baseResult = (HGRandomAccessResult<T>)query.execute();
try
{
while (baseResult.hasNext())
{
T next = baseResult.next();
if (predicate.eval(next))
return new FilteredRAResultSet<T>(baseResult, predicate, 1);
}
}
catch (Throwable t)
{
HGUtils.closeNoException(baseResult);
HGUtils.wrapAndRethrow(t);
}
baseResult.close();
return (HGSearchResult<T>)HGSearchResult.EMPTY;
}
}