package org.neo4j.rdf.sparql;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;
import name.levering.ryan.sparql.common.LenientStatement;
import name.levering.ryan.sparql.common.RdfGraph;
import name.levering.ryan.sparql.common.RdfSource;
import name.levering.ryan.sparql.common.impl.StatementImpl;
import name.levering.ryan.sparql.model.data.ConstructQueryData;
import name.levering.ryan.sparql.model.data.UnboundStatement;
import name.levering.ryan.sparql.model.logic.ConstructQueryLogic;
import name.levering.ryan.sparql.model.logic.ExpressionLogic;
import org.neo4j.rdf.store.representation.RepresentationStrategy;
import org.openrdf.model.URI;
public class Neo4jConstructQueryLogic extends AbstractNeo4jQueryLogic implements
ConstructQueryLogic
{
private ConstructQueryData data;
public Neo4jConstructQueryLogic( ConstructQueryData data,
RepresentationStrategy representationStrategy,
MetaModelProxy metaModel )
{
super( representationStrategy, metaModel );
this.data = data;
}
public RdfGraph execute( RdfSource source )
{
QueryGraph graph = this.buildGraph( this.data.getConstraint() );
Neo4jRdfBindingSet bindingSet = new Neo4jRdfBindingSet(
this.getNeo4jVariables(), this.performMatches( graph ) );
return new Neo4jRdfGraph( this.data.getTriples(), bindingSet );
}
@Override
protected List<Neo4jVariable> getNeo4jVariables()
{
List<Neo4jVariable> variables = new LinkedList<Neo4jVariable>();
for ( Neo4jVariable variable : super.getNeo4jVariables() )
{
if ( this.variableExists(
this.data.getVariables(), variable.getName() ) )
{
variables.add( variable );
}
}
return variables;
}
}
class Neo4jRdfGraph implements RdfGraph, Iterable<LenientStatement>
{
private Collection<UnboundStatement> triples;
private Neo4jRdfBindingSet bindingSet;
RdfGraphIterator iterator;
public Neo4jRdfGraph( Collection<UnboundStatement> triples,
Neo4jRdfBindingSet bindingSet )
{
this.triples = triples;
this.bindingSet = bindingSet;
this.iterator = new RdfGraphIterator();
}
public Iterator<LenientStatement> iterator()
{
return this.iterator;
}
class RdfGraphIterator implements Iterator<LenientStatement>
{
private Iterator<Neo4jBindingRow> bindingRows;
private Iterator<LenientStatement> currentTriples;
public RdfGraphIterator()
{
this.bindingRows = bindingSet.iterator();
}
public boolean hasNext()
{
if ( this.currentTriples == null )
{
this.currentTriples = this.getNextTriples();
}
return this.currentTriples != null;
}
public LenientStatement next()
{
if ( this.currentTriples == null ||
!this.currentTriples.hasNext() )
{
this.currentTriples = this.getNextTriples();
if ( this.currentTriples == null )
{
throw new NoSuchElementException();
}
}
LenientStatement statementToReturn = this.currentTriples.next();
if ( !this.currentTriples.hasNext() )
{
this.currentTriples = null;
}
return statementToReturn;
}
private Iterator<LenientStatement> getNextTriples()
{
if ( !this.bindingRows.hasNext() )
{
return null;
}
List<LenientStatement> boundStatements =
new ArrayList<LenientStatement>();
Neo4jBindingRow bindingRow = this.bindingRows.next();
for ( UnboundStatement unboundStatement : triples )
{
LenientStatement statement = new StatementImpl(
unboundStatement.getSubjectExpression().evaluate( bindingRow ),
this.toUri( unboundStatement.getPredicateExpression() ),
unboundStatement.getObjectExpression().evaluate(
bindingRow ) );
boundStatements.add( statement );
}
return boundStatements.iterator();
}
private URI toUri( ExpressionLogic predicateExpression )
{
return ( URI ) predicateExpression;
}
public void remove()
{
throw new UnsupportedOperationException( "Remove not supported." );
}
}
}