package org.neo4j.rdf.sparql;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import name.levering.ryan.sparql.common.RdfBindingSet;
import name.levering.ryan.sparql.common.RdfGraph;
import name.levering.ryan.sparql.model.ConstructQuery;
import name.levering.ryan.sparql.model.Query;
import name.levering.ryan.sparql.model.SelectQuery;
import org.neo4j.meta.model.ClassRange;
import org.neo4j.meta.model.DatatypeClassRange;
import org.neo4j.meta.model.MetaModel;
import org.neo4j.meta.model.MetaModelClass;
import org.neo4j.meta.model.MetaModelImpl;
import org.neo4j.meta.model.MetaModelNamespace;
import org.neo4j.meta.model.MetaModelProperty;
import org.neo4j.rdf.model.CompleteStatement;
import org.neo4j.rdf.model.Context;
import org.neo4j.rdf.model.Literal;
import org.neo4j.rdf.model.Resource;
import org.neo4j.rdf.model.Uri;
import org.neo4j.rdf.store.RdfStore;
import org.neo4j.rdf.store.VerboseQuadStore;
import org.neo4j.rdf.store.representation.RepresentationExecutor;
import org.neo4j.rdf.store.representation.RepresentationStrategy;
import org.neo4j.rdf.store.representation.standard.VerboseQuadExecutor;
import org.neo4j.rdf.store.representation.standard.VerboseQuadStrategy;
public class Om2SampleQueriesTest extends SparqlTestCase
{
interface Predicates
{
String TYPE = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type";
String COURSE_ID = "http://www.swami.se/om2/ladok-1.owl#courseId";
String NAME = "http://www.openmetadir.org/om2/prim-1.owl#name";
String NICK = "http://www.openmetadir.org/om2/prim-1.owl#nick";
String ONE = "http://www.openmetadir.org/om2/prim-1.owl#one";
String OTHER = "http://www.openmetadir.org/om2/prim-1.owl#other";
String STATE = "http://www.swami.se/om2/ladok-1.owl#state";
}
interface Types
{
Uri STUDENT = new Uri(
"http://www.swami.se/om2/ladok-1.owl#Student" );
Uri PERSON = new Uri(
"http://www.openmetadir.org/om2/prim-1.owl#Person" );
Uri COURSE = new Uri(
"http://www.swami.se/om2/ladok-1.owl#CourseInstance" );
Uri DEPARTMENT = new Uri(
"http://www.openmetadir.org/om2/prim-1.owl#Department" );
Uri RESPONSIBLE = new Uri(
"http://www.openmetadir.org/om2/prim-1.owl#Responsible" );
}
private static Map<String, Integer> counts =
new HashMap<String, Integer>();
private RdfStore rdfStore;
private static MetaModel metaModel;
static
{
counts.put( PRIM_NAMESPACE + "Person", new Integer( 10 ) );
counts.put( PRIM_NAMESPACE + "Department", new Integer( 2 ) );
counts.put( PRIM_NAMESPACE + "Responsible", new Integer( 3 ) );
counts.put( LADOK_NAMESPACE + "Student", new Integer( 10 ) );
counts.put( LADOK_NAMESPACE + "CourseInstance", new Integer( 5 ) );
}
@Override
protected RepresentationStrategy instantiateRepresentationStrategy()
{
RepresentationExecutor executor = new VerboseQuadExecutor( graphDb(),
indexService(), metaModel(), null );
return new VerboseQuadStrategy( executor, metaModel() );
}
@Override
protected MetaModelMockUp instantiateMetaModelProxy()
{
return new MetaModelMockUp( metaModel(), counts );
}
@Override
protected Neo4jSparqlEngine instantiateSparqlEngine()
{
return new Neo4jSparqlEngine( representationStrategy(),
metaModelProxy() );
}
private MetaModel metaModel()
{
if ( metaModel == null )
{
metaModel = new MetaModelImpl( graphDb() );
MetaModelNamespace namespace =
metaModel.getGlobalNamespace();
MetaModelClass studentClass = namespace.getMetaClass(
Types.STUDENT.getUriAsString(), true );
MetaModelClass personClass = namespace.getMetaClass(
Types.PERSON.getUriAsString(), true );
MetaModelClass courseClass = namespace.getMetaClass(
Types.COURSE.getUriAsString(), true );
MetaModelClass departmentClass = namespace.getMetaClass(
Types.DEPARTMENT.getUriAsString(), true );
MetaModelClass responsibleClass = namespace.getMetaClass(
Types.RESPONSIBLE.getUriAsString(), true );
MetaModelProperty courseId = namespace.getMetaProperty(
Predicates.COURSE_ID, true );
courseId.setRange( new DatatypeClassRange( String.class ) );
MetaModelProperty name = namespace.getMetaProperty(
Predicates.NAME, true );
name.setRange( new DatatypeClassRange( String.class ) );
MetaModelProperty nick = namespace.getMetaProperty(
Predicates.NICK, true );
nick.setRange( new DatatypeClassRange( String.class ) );
MetaModelProperty one = namespace.getMetaProperty(
Predicates.ONE, true );
one.setRange( new ClassRange( personClass ) );
MetaModelProperty other = namespace.getMetaProperty(
Predicates.OTHER, true );
other.setRange( new ClassRange( courseClass ) );
MetaModelProperty state = namespace.getMetaProperty(
Predicates.STATE, true );
state.setRange( new DatatypeClassRange( String.class ) );
}
return metaModel;
}
@Override
public void setUp() throws Exception
{
super.setUp();
this.rdfStore = new VerboseQuadStore( graphDb(), indexService(),
metaModel(), null );
List<CompleteStatement> statements = new ArrayList<CompleteStatement>();
statements.add( this.createStatement(
"studentA", Predicates.TYPE, Types.STUDENT ) );
statements.add( this.createStatement(
"studentB", Predicates.TYPE, Types.STUDENT ) );
statements.add( this.createStatement(
"studentC", Predicates.TYPE, Types.STUDENT ) );
statements.add( this.createStatement(
"studentD", Predicates.TYPE, Types.STUDENT ) );
statements.add( this.createStatement(
"studentE", Predicates.TYPE, Types.STUDENT ) );
statements.add( this.createStatement(
"studentF", Predicates.TYPE, Types.STUDENT ) );
statements.add( this.createStatement(
"personA", Predicates.TYPE, Types.PERSON ) );
statements.add( this.createStatement(
"personB", Predicates.TYPE, Types.PERSON ) );
statements.add( this.createStatement(
"personC", Predicates.TYPE, Types.PERSON ) );
statements.add( this.createStatement(
"personD", Predicates.TYPE, Types.PERSON ) );
statements.add( this.createStatement(
"personE", Predicates.TYPE, Types.PERSON ) );
statements.add( this.createStatement(
"personF", Predicates.TYPE, Types.PERSON ) );
statements.add( this.createStatement(
"http://28040ht06", Predicates.TYPE, Types.COURSE ) );
statements.add( this.createStatement(
"courseB", Predicates.TYPE, Types.COURSE ) );
statements.add( this.createStatement(
"courseB", Predicates.COURSE_ID, "KOSB15" ) );
statements.add( this.createStatement(
"courseC", Predicates.TYPE, Types.COURSE ) );
statements.add( this.createStatement(
"courseD", Predicates.TYPE, Types.COURSE ) );
statements.add( this.createStatement(
"courseD", Predicates.COURSE_ID, "TMHB21" ) );
statements.add( this.createStatement(
"courseE", Predicates.TYPE, Types.COURSE ) );
statements.add( this.createStatement(
"departmentA", Predicates.TYPE, Types.DEPARTMENT ) );
statements.add( this.createStatement(
"departmentA", Predicates.NAME, "Psykologi" ) );
statements.add( this.createStatement(
"departmentB", Predicates.TYPE, Types.DEPARTMENT ) );
statements.add( this.createStatement(
"responsibleA", Predicates.TYPE, Types.RESPONSIBLE ) );
statements.add( this.createStatement(
"responsibleB", Predicates.TYPE, Types.RESPONSIBLE ) );
statements.add( this.createStatement( "responsibleA",
Predicates.ONE, new Uri( "departmentA" ) ) );
statements.add( this.createStatement( "responsibleB",
Predicates.ONE, new Uri( "departmentB" ) ) );
statements.add( this.createStatement( "responsibleA",
Predicates.OTHER, new Uri( "http://28040ht06" ) ) );
statements.add( this.createStatement(
"responsibleA", Predicates.OTHER, new Uri( "courseD" ) ) );
statements.add( this.createStatement(
"responsibleB", Predicates.OTHER, new Uri( "courseB" ) ) );
statements.add( this.createStatement(
"responsibleB", Predicates.OTHER, new Uri( "courseC" ) ) );
statements.add( this.createStatement(
"studentA", Predicates.ONE, new Uri( "personA" ) ) );
statements.add( this.createStatement(
"studentB", Predicates.ONE, new Uri( "personB" ) ) );
statements.add( this.createStatement(
"studentC", Predicates.ONE, new Uri( "personC" ) ) );
statements.add( this.createStatement(
"studentD", Predicates.ONE, new Uri( "personD" ) ) );
statements.add( this.createStatement(
"studentE", Predicates.ONE, new Uri( "personE" ) ) );
statements.add( this.createStatement(
"studentF", Predicates.ONE, new Uri( "personF" ) ) );
statements.add( this.createStatement(
"studentA", Predicates.STATE, "registered" ) );
statements.add( this.createStatement(
"studentC", Predicates.STATE, "registered" ) );
statements.add( this.createStatement(
"studentD", Predicates.STATE, "registered" ) );
statements.add( this.createStatement(
"studentE", Predicates.STATE, "accepted" ) );
statements.add( this.createStatement(
"studentF", Predicates.STATE, "accepted" ) );
statements.add( this.createStatement( "studentA", Predicates.OTHER,
new Uri( "http://28040ht06" ) ) );
statements.add( this.createStatement(
"studentA", Predicates.OTHER, new Uri( "courseE" ) ) );
statements.add( this.createStatement( "studentC", Predicates.OTHER,
new Uri( "http://28040ht06" ) ) );
statements.add( this.createStatement(
"studentD", Predicates.OTHER, new Uri( "courseB" ) ) );
statements.add( this.createStatement( "studentE", Predicates.OTHER,
new Uri( "http://28040ht06" ) ) );
statements.add( this.createStatement(
"studentF", Predicates.OTHER, new Uri( "courseB" ) ) );
this.rdfStore.addStatements( statements.toArray(
new CompleteStatement[] {} ) );
}
private CompleteStatement createStatement(
String subjectString, String predicateString, String objectString )
{
Resource subject = new Uri( subjectString );
Uri predicate = new Uri( predicateString );
Literal object = new Literal( objectString );
return new CompleteStatement( subject, predicate, object,
Context.NULL );
}
private CompleteStatement createStatement(
String subjectString, String predicateString, Uri objectUri )
{
Resource subject = new Uri( subjectString );
Uri predicate = new Uri( predicateString );
return new CompleteStatement( subject, predicate, objectUri,
Context.NULL );
}
public void testQuery1() throws Exception
{
// Which students are registered on the course 28040ht06?
Query query = sparqlEngine().parse( new StringReader(
"PREFIX prim: <http://www.openmetadir.org/om2/prim-1.owl#> " +
"PREFIX ladok: <http://www.swami.se/om2/ladok-1.owl#> " +
"PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> " +
"SELECT ?student ?person " +
"WHERE { " +
"?student rdf:type ladok:Student . " +
"?person rdf:type prim:Person . " +
"?student prim:one ?person . " +
"?student ladok:state \"registered\" . " +
"?student prim:other <http://28040ht06> . " +
"<http://28040ht06> rdf:type ladok:CourseInstance . }" ) );
RdfBindingSet result =
( ( SelectQuery ) query ).execute( new Neo4jRdfSource() );
Map<String, Integer> variables =
this.createVariableMap( "student", "person" );
List<List<String>> expectedResult = new ArrayList<List<String>>();
expectedResult.add( Arrays.asList( "studentC", "personC" ) );
expectedResult.add( Arrays.asList( "studentA", "personA" ) );
this.assertResult( result, variables, expectedResult );
}
public void testQuery2() throws Exception
{
// Which students are accepted to the course KOSB15?
Query query = sparqlEngine().parse( new StringReader(
"PREFIX prim: <http://www.openmetadir.org/om2/prim-1.owl#> " +
"PREFIX ladok: <http://www.swami.se/om2/ladok-1.owl#> " +
"PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> " +
"SELECT ?student ?person ?course " +
"WHERE { " +
"?student rdf:type ladok:Student . " +
"?student prim:one ?person . " +
"?person rdf:type prim:Person . " +
"?student ladok:state \"accepted\" . " +
"?student prim:other ?course . " +
"?course rdf:type ladok:CourseInstance . " +
"?course ladok:courseId ?course_id ." +
"FILTER( regex( ?course_id, \"B15$\" ) )" +
"} " ) );
RdfBindingSet result =
( ( SelectQuery ) query ).execute( new Neo4jRdfSource() );
Map<String, Integer> variables =
this.createVariableMap( "student", "person", "course" );
List<List<String>> expectedResult = new ArrayList<List<String>>();
expectedResult.add( Arrays.asList( "studentF", "personF", "courseB" ) );
this.assertResult( result, variables, expectedResult );
}
public void testQuery3() throws Exception
{
// Which courses are the Psychology department responsible for?
Query query = sparqlEngine().parse( new StringReader(
"PREFIX prim: <http://www.openmetadir.org/om2/prim-1.owl#> " +
"PREFIX ladok: <http://www.swami.se/om2/ladok-1.owl#> " +
"PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> " +
"SELECT ?responsible ?course ?department " +
"WHERE { " +
"?responsible rdf:type prim:Responsible . " +
"?responsible prim:other ?course . " +
"?course rdf:type ladok:CourseInstance . " +
"?responsible prim:one ?department . " +
"?department rdf:type prim:Department . " +
"?department prim:name \"Psykologi\" } " ) );
RdfBindingSet result =
( ( SelectQuery ) query ).execute( new Neo4jRdfSource() );
Map<String, Integer> variables = this.createVariableMap(
"responsible", "course", "department" );
List<List<String>> expectedResult = new ArrayList<List<String>>();
expectedResult.add( Arrays.asList(
"responsibleA", "courseD", "departmentA" ) );
expectedResult.add( Arrays.asList(
"responsibleA", "http://28040ht06", "departmentA" ) );
this.assertResult( result, variables, expectedResult );
}
public void testQuery4() throws Exception
{
// Which department is responsible for the course TMHB21?
Query query = sparqlEngine().parse( new StringReader(
"PREFIX prim: <http://www.openmetadir.org/om2/prim-1.owl#> " +
"PREFIX ladok: <http://www.swami.se/om2/ladok-1.owl#> " +
"PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> " +
"SELECT ?responsible ?course ?department ?name " +
"WHERE { " +
"?responsible rdf:type prim:Responsible . " +
"?responsible prim:other ?course . " +
"?course rdf:type ladok:CourseInstance . " +
"?course ladok:courseId \"TMHB21\" . " +
"?responsible prim:one ?department . " +
"?department rdf:type prim:Department . " +
"?department prim:name ?name }" ) );
RdfBindingSet result =
( ( SelectQuery ) query ).execute( new Neo4jRdfSource() );
Map<String, Integer> variables = this.createVariableMap(
"responsible", "course", "department", "name" );
List<List<String>> expectedResult = new ArrayList<List<String>>();
expectedResult.add( Arrays.asList(
"responsibleA", "courseD", "departmentA", "Psykologi" ) );
this.assertResult( result, variables, expectedResult );
}
public void testQuery5() throws Exception
{
// Which department is responsible for the non-existing course
// TDDB56?
Query query = sparqlEngine().parse( new StringReader(
"PREFIX prim: <http://www.openmetadir.org/om2/prim-1.owl#> " +
"PREFIX ladok: <http://www.swami.se/om2/ladok-1.owl#> " +
"PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> " +
"SELECT ?responsible ?course ?department ?name " +
"WHERE { " +
"?responsible rdf:type prim:Responsible . " +
"?responsible prim:other ?course . " +
"?course rdf:type ladok:CourseInstance . " +
"?course ladok:courseId \"TDDB56\" . " +
"?responsible prim:one ?department . " +
"?department rdf:type prim:Department . " +
"?department prim:name ?name }" ) );
RdfBindingSet result =
( ( SelectQuery ) query ).execute( new Neo4jRdfSource() );
this.assertResult( result, null, null );
}
public void testQuery6() throws Exception
{
// Get all students
// Optional: The person the student is connected to
// Optional: Every course the student takes
// Optional: The student's registration status
Query query = sparqlEngine().parse( new StringReader(
"PREFIX prim: <http://www.openmetadir.org/om2/prim-1.owl#> " +
"PREFIX ladok: <http://www.swami.se/om2/ladok-1.owl#> " +
"PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> " +
"SELECT ?student ?person ?course ?state " +
"WHERE { " +
"?student rdf:type ladok:Student . " +
"OPTIONAL { ?student prim:other ?course . " +
"?course rdf:type ladok:CourseInstance } " +
"OPTIONAL { ?student prim:one ?person . " +
"?person rdf:type prim:Person } " +
"OPTIONAL { ?student ladok:state ?state } " +
"}" ) );
RdfBindingSet result =
( ( SelectQuery ) query ).execute( new Neo4jRdfSource() );
Map<String, Integer> variables =
this.createVariableMap( "student", "person", "course", "state" );
List<List<String>> expectedResult = new ArrayList<List<String>>();
expectedResult.add( Arrays.asList(
"studentF", "personF", "courseB", "accepted" ) );
expectedResult.add( Arrays.asList(
"studentE", "personE", "http://28040ht06", "accepted" ) );
expectedResult.add( Arrays.asList(
"studentD", "personD", "courseB", "registered" ) );
expectedResult.add( Arrays.asList(
"studentC", "personC", "http://28040ht06", "registered" ) );
expectedResult.add( Arrays.asList(
"studentB", "personB", "", "" ) );
expectedResult.add( Arrays.asList(
"studentA", "personA", "courseE", "registered" ) );
expectedResult.add( Arrays.asList(
"studentA", "personA", "http://28040ht06", "registered" ) );
this.assertResult( result, variables, expectedResult );
}
public void testQuery7() throws Exception
{
// Construct a new rdf graph from all students/persons
// ( The new graph doesn't make sense, but hey... ;) )
Query query = sparqlEngine().parse( new StringReader(
"PREFIX prim: <http://www.openmetadir.org/om2/prim-1.owl#> " +
"PREFIX ladok: <http://www.swami.se/om2/ladok-1.owl#> " +
"PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> " +
"CONSTRUCT { ?student prim:one ?person . " +
"?person prim:other ?student } " +
"WHERE { " +
"?student rdf:type ladok:Student . " +
"?student prim:one ?person . " +
"?person rdf:type prim:Person " +
"}" ) );
RdfGraph result =
( ( ConstructQuery ) query ).execute( new Neo4jRdfSource() );
List<String> expectedResult = new ArrayList<String>();
expectedResult.add(
"(studentF, http://www.openmetadir.org/om2/prim-1.owl#one, personF)" );
expectedResult.add(
"(personF, http://www.openmetadir.org/om2/prim-1.owl#other, studentF)" );
expectedResult.add(
"(studentE, http://www.openmetadir.org/om2/prim-1.owl#one, personE)" );
expectedResult.add(
"(personE, http://www.openmetadir.org/om2/prim-1.owl#other, studentE)" );
expectedResult.add(
"(studentD, http://www.openmetadir.org/om2/prim-1.owl#one, personD)" );
expectedResult.add(
"(personD, http://www.openmetadir.org/om2/prim-1.owl#other, studentD)" );
expectedResult.add(
"(studentC, http://www.openmetadir.org/om2/prim-1.owl#one, personC)" );
expectedResult.add(
"(personC, http://www.openmetadir.org/om2/prim-1.owl#other, studentC)" );
expectedResult.add(
"(studentB, http://www.openmetadir.org/om2/prim-1.owl#one, personB)" );
expectedResult.add(
"(personB, http://www.openmetadir.org/om2/prim-1.owl#other, studentB)" );
expectedResult.add(
"(studentA, http://www.openmetadir.org/om2/prim-1.owl#one, personA)" );
expectedResult.add(
"(personA, http://www.openmetadir.org/om2/prim-1.owl#other, studentA)" );
this.assertResult( ( Neo4jRdfGraph ) result, expectedResult );
}
}