public CloseableIteration<BindingSet, QueryEvaluationException> evaluate(StatementPattern sp,
final BindingSet bindings)
throws QueryEvaluationException
{
final Var subjVar = sp.getSubjectVar();
final Var predVar = sp.getPredicateVar();
final Var objVar = sp.getObjectVar();
final Var conVar = sp.getContextVar();
Value subjValue = getVarValue(subjVar, bindings);
Value predValue = getVarValue(predVar, bindings);
Value objValue = getVarValue(objVar, bindings);
Value contextValue = getVarValue(conVar, bindings);
CloseableIteration<? extends Statement, QueryEvaluationException> stIter = null;
try {
Resource[] contexts;
if (dataset != null) {
Set<URI> graphs;
if (sp.getScope() == Scope.DEFAULT_CONTEXTS) {
graphs = dataset.getDefaultGraphs();
}
else {
graphs = dataset.getNamedGraphs();
}
if (graphs.isEmpty()) {
// Search zero contexts
return new EmptyIteration<BindingSet, QueryEvaluationException>();
}
else if (contextValue != null) {
if (graphs.contains(contextValue)) {
contexts = new Resource[] { (Resource)contextValue };
}
else {
// Statement pattern specifies a context that is not part of
// the dataset
return new EmptyIteration<BindingSet, QueryEvaluationException>();
}
}
else {
contexts = graphs.toArray(new Resource[graphs.size()]);
}
}
else if (contextValue != null) {
contexts = new Resource[] { (Resource)contextValue };
}
else {
contexts = new Resource[0];
}
stIter = tripleSource.getStatements((Resource)subjValue, (URI)predValue, objValue, contexts);
if (contexts.length == 0 && sp.getScope() == Scope.NAMED_CONTEXTS) {
// Named contexts are matched by retrieving all statements from
// the store and filtering out the statements that do not have a
// context.
stIter = new FilterIteration<Statement, QueryEvaluationException>(stIter) {
@Override
protected boolean accept(Statement st) {
return st.getContext() != null;
}
}; // end anonymous class
}
}
catch (ClassCastException e) {
// Invalid value type for subject, predicate and/or context
return new EmptyIteration<BindingSet, QueryEvaluationException>();
}
// The same variable might have been used multiple times in this
// StatementPattern, verify value equality in those cases.
stIter = new FilterIteration<Statement, QueryEvaluationException>(stIter) {
@Override
protected boolean accept(Statement st) {
Resource subj = st.getSubject();
URI pred = st.getPredicate();
Value obj = st.getObject();
Resource context = st.getContext();
if (subjVar != null) {
if (subjVar.equals(predVar) && !subj.equals(pred)) {
return false;
}
if (subjVar.equals(objVar) && !subj.equals(obj)) {
return false;
}
if (subjVar.equals(conVar) && !subj.equals(context)) {
return false;
}
}
if (predVar != null) {
if (predVar.equals(objVar) && !pred.equals(obj)) {
return false;
}
if (predVar.equals(conVar) && !pred.equals(context)) {
return false;
}
}
if (objVar != null) {
if (objVar.equals(conVar) && !obj.equals(context)) {
return false;
}
}
return true;
}
};
// Return an iterator that converts the statements to var bindings
return new ConvertingIteration<Statement, BindingSet, QueryEvaluationException>(stIter) {
@Override
protected BindingSet convert(Statement st) {
QueryBindingSet result = new QueryBindingSet(bindings);
if (subjVar != null && !result.hasBinding(subjVar.getName())) {
result.addBinding(subjVar.getName(), st.getSubject());
}
if (predVar != null && !result.hasBinding(predVar.getName())) {
result.addBinding(predVar.getName(), st.getPredicate());
}
if (objVar != null && !result.hasBinding(objVar.getName())) {
result.addBinding(objVar.getName(), st.getObject());
}
if (conVar != null && !result.hasBinding(conVar.getName()) && st.getContext() != null) {
result.addBinding(conVar.getName(), st.getContext());
}
return result;
}
};