package org.neo4j.rdf.sparql;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import name.levering.ryan.sparql.common.Variable;
import name.levering.ryan.sparql.model.GroupConstraint;
import org.neo4j.graphmatching.PatternMatch;
import org.neo4j.graphmatching.PatternMatcher;
import org.neo4j.graphmatching.PatternNode;
import org.neo4j.rdf.store.representation.RepresentationStrategy;
public abstract class AbstractNeo4jQueryLogic
{
private List<Neo4jVariable> variableList = new LinkedList<Neo4jVariable>();
private MetaModelProxy metaModel;
private RepresentationStrategy representationStrategy;
AbstractNeo4jQueryLogic( RepresentationStrategy representationStrategy,
MetaModelProxy metaModel )
{
this.metaModel = metaModel;
this.representationStrategy = representationStrategy;
}
protected List<Neo4jVariable> getNeo4jVariables()
{
return this.variableList;
}
private Map<String, PatternNode> getObjectVariables()
{
Map<String, PatternNode> map = new HashMap<String, PatternNode>();
for ( Neo4jVariable variable : this.variableList )
{
map.put( variable.getName(), variable.getNode() );
}
return map;
}
protected boolean variableExists( Collection<Variable> variables,
String variableName )
{
for ( Variable variable : variables )
{
if ( variableName.equals( variable.getName() ) )
{
return true;
}
}
return false;
}
protected Iterable<PatternMatch> performMatches( QueryGraph graph )
{
ArrayList<Iterable<PatternMatch>> results =
new ArrayList<Iterable<PatternMatch>>();
PatternNodeAndNodePair startNode = graph.getStartNode();
PatternNode patternNode = startNode.getPatternNode();
// For (not-very-optimized) inferencing
// String[] types =
// this.metaModel.getSubTypes( patternNode.getLabel(), true );
// for ( String type : types )
// {
// results.add( PatternMatcher.getMatcher().match( patternNode,
// startNode.getNode(), getObjectVariables(),
// graph.getOptionalGraphs() ) );
// }
results.add( PatternMatcher.getMatcher().match( patternNode,
startNode.getNode(), getObjectVariables(),
graph.getOptionalGraphs() ) );
return new PatternMatchesWrapper( results );
}
// private Iterable<PatternNode> getStartNodes(
// PatternNode startNode )
// {
// ArrayList<PatternNode> startNodes = new ArrayList<PatternNode>();
// startNodes.add( startNode );
// return startNodes;
// }
protected QueryGraph buildGraph( GroupConstraint groupConstraint )
{
QueryGraph graph = new QueryGraph( this.representationStrategy,
this.metaModel, this.variableList );
graph.build( groupConstraint );
// graph.assertGraph();
return graph;
}
private class PatternMatchesWrapper
implements Iterable<PatternMatch>, Iterator<PatternMatch>
{
private Iterator<Iterable<PatternMatch>> matches;
private Iterator<PatternMatch> current;
PatternMatchesWrapper( Iterable<Iterable<PatternMatch>> matches )
{
this.matches = matches.iterator();
if ( this.matches.hasNext() )
{
this.current = this.matches.next().iterator();
}
}
public Iterator<PatternMatch> iterator()
{
return this;
}
public boolean hasNext()
{
if ( this.current == null )
{
return false;
}
else if ( this.current.hasNext() )
{
return true;
}
else if ( this.matches.hasNext() )
{
this.current = this.matches.next().iterator();
// recursive call so we don't stop if there's an empty iterator
// in the middle of this.matches.
return this.hasNext();
}
return false;
}
public PatternMatch next()
{
if ( this.current != null && this.current.hasNext() )
{
return this.current.next();
}
else if ( this.matches.hasNext() )
{
this.current = this.matches.next().iterator();
// recursive call so we don't return null if there's an empty
// iterator in the middle of this.matches.
return this.next();
}
else
{
return null;
}
}
public void remove()
{
throw new RuntimeException( "Remove is not supported" );
}
}
}