package com.tinkerpop.blueprints.oupls.sail;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Graph;
import com.tinkerpop.blueprints.KeyIndexableGraph;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.tg.TinkerGraph;
import info.aduna.iteration.CloseableIteration;
import org.junit.Test;
import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.model.ValueFactory;
import org.openrdf.model.impl.LiteralImpl;
import org.openrdf.model.impl.URIImpl;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.model.vocabulary.RDFS;
import org.openrdf.query.BindingSet;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.query.impl.EmptyBindingSet;
import org.openrdf.query.parser.ParsedQuery;
import org.openrdf.query.parser.sparql.SPARQLParser;
import org.openrdf.rio.RDFFormat;
import org.openrdf.sail.Sail;
import org.openrdf.sail.SailConnection;
import org.openrdf.sail.SailException;
import java.io.File;
import java.net.URL;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
/**
* @author Joshua Shinavier (http://fortytwo.net)
*/
public abstract class GraphSailTest extends SailTest {
protected abstract KeyIndexableGraph createGraph() throws Exception;
protected KeyIndexableGraph graph;
protected Sail createSail() throws Exception {
// Flip this flag in order to disable "unique statements" behavior
uniqueStatements = true;
graph = createGraph();
GraphSail<KeyIndexableGraph> g = new GraphSail<KeyIndexableGraph>(graph);
g.enforceUniqueStatements(uniqueStatements);
return g;
}
protected void before() throws Exception {
// Nothing to do.
}
protected void after() throws Exception {
// Nothing to do.
}
@Test
public void testIsolatedVerticesAutomaticallyDeleted() throws Exception {
String ex = "http://example.org/ns#";
URI ref = new URIImpl(ex + "Ref");
clear();
int edgesBefore, verticesBefore;
SailConnection sc = sail.getConnection();
try {
sc.begin();
edgesBefore = countEdges();
verticesBefore = countVertices();
} finally {
sc.commit();
sc.close();
}
addFile(SailTest.class.getResourceAsStream("graph-example-bnodes.trig"), RDFFormat.TRIG);
sc = sail.getConnection();
//showStatements(sc, null, null, null);
try {
sc.begin();
assertEquals(14, countStatements(sc, null, null, null, false));
assertEquals(edgesBefore + 14, countEdges());
assertEquals(verticesBefore + 10, countVertices());
sc.removeStatements(ref, null, null);
sc.commit();
sc.begin();
assertEquals(13, countStatements(sc, null, null, null, false));
assertEquals(edgesBefore + 13, countEdges());
assertEquals(verticesBefore + 9, countVertices());
sc.clear();
sc.commit();
sc.begin();
assertEquals(0, countStatements(sc, null, null, null, false));
assertEquals(0, countEdges());
// Namespaces vertex is still present.
assertEquals(verticesBefore, countVertices());
} finally {
sc.rollback();
sc.close();
}
}
@Test
public void testBlankNodesUnique() throws Exception {
String ex = "http://example.org/ns#";
URI class1 = new URIImpl(ex + "Class1");
clear();
int edgesBefore, verticesBefore;
SailConnection sc = sail.getConnection();
try {
sc.begin();
edgesBefore = countEdges();
verticesBefore = countVertices();
} finally {
sc.rollback();
sc.close();
}
// Load a file once.
addFile(SailTest.class.getResourceAsStream("graph-example-bnodes.trig"), RDFFormat.TRIG);
sc = sail.getConnection();
try {
assertEquals(3, countStatements(sc, class1, RDFS.SUBCLASSOF, null, false));
assertEquals(edgesBefore + 14, countEdges());
assertEquals(verticesBefore + 10, countVertices());
} finally {
sc.rollback();
sc.close();
}
// Load the file again.
// Loading the same file twice results in extra vertices and edges,
// since blank nodes assume different identities on each load.
addFile(SailTest.class.getResourceAsStream("graph-example-bnodes.trig"), RDFFormat.TRIG);
sc = sail.getConnection();
try {
assertEquals(5, countStatements(sc, class1, RDFS.SUBCLASSOF, null, false));
assertEquals(edgesBefore + 23, countEdges());
assertEquals(verticesBefore + 12, countVertices());
} finally {
sc.rollback();
sc.close();
}
}
@Test
public void testIndexPatterns() throws Exception {
assertTriplePattern("spoc", true);
assertTriplePattern("poc", true);
assertTriplePattern("p", true);
assertTriplePattern("", true);
assertTriplePattern("xpoc", false);
assertTriplePattern("sspo", false);
}
@Test
public void testAddVertex() throws Exception {
GraphSail gSail = (GraphSail) sail;
Value toAdd = new URIImpl("http://example.org/thelarch");
assertNull(gSail.getVertex(toAdd));
int count = countVertices();
Vertex added = gSail.addVertex(toAdd);
assertNotNull(added);
assertEquals(1 + count, countVertices());
assertEquals("http://example.org/thelarch", added.getProperty(GraphSail.VALUE));
// also test that we get the vertex through getVertex
added = gSail.getVertex(toAdd);
assertNotNull(added);
assertEquals("http://example.org/thelarch", added.getProperty(GraphSail.VALUE));
}
@Test
public void getGetVertex() throws Exception {
GraphSail gSail = (GraphSail) sail;
SailConnection sc = gSail.getConnection();
try {
sc.begin();
Vertex type = gSail.getVertex(RDF.TYPE);
assertNull(type);
sc.addStatement(RDF.TYPE, RDFS.LABEL, new LiteralImpl("type"));
type = gSail.getVertex(RDF.TYPE);
assertNotNull(type);
assertEquals(RDF.TYPE.stringValue(), type.getProperty(GraphSail.VALUE));
} finally {
sc.rollback();
sc.close();
}
}
@Test
public void testCodePlay() throws Exception {
Sail sail = new GraphSail(new TinkerGraph());
sail.initialize();
try {
SailConnection sc = sail.getConnection();
try {
sc.begin();
ValueFactory vf = sail.getValueFactory();
sc.addStatement(vf.createURI("http://tinkerpop.com#1"), vf.createURI("http://tinkerpop.com#knows"), vf.createURI("http://tinkerpop.com#3"), vf.createURI("http://tinkerpop.com"));
sc.addStatement(vf.createURI("http://tinkerpop.com#1"), vf.createURI("http://tinkerpop.com#name"), vf.createLiteral("marko"), vf.createURI("http://tinkerpop.com"));
sc.addStatement(vf.createURI("http://tinkerpop.com#3"), vf.createURI("http://tinkerpop.com#name"), vf.createLiteral("josh"), vf.createURI("http://tinkerpop.com"));
CloseableIteration<? extends Statement, SailException> results = sc.getStatements(null, null, null, false);
try {
System.out.println("get statements: ?s ?p ?o ?g");
while (results.hasNext()) {
System.out.println(results.next());
}
} finally {
results.close();
}
System.out.println("\nget statements: http://tinkerpop.com#3 ?p ?o ?g");
results = sc.getStatements(vf.createURI("http://tinkerpop.com#3"), null, null, false);
try {
while (results.hasNext()) {
System.out.println(results.next());
}
} finally {
results.close();
}
SPARQLParser parser = new SPARQLParser();
CloseableIteration<? extends BindingSet, QueryEvaluationException> sparqlResults;
String queryString = "SELECT ?x ?y WHERE { ?x <http://tinkerpop.com#knows> ?y }";
ParsedQuery query = parser.parseQuery(queryString, "http://tinkerPop.com");
System.out.println("\nSPARQL: " + queryString);
sparqlResults = sc.evaluate(query.getTupleExpr(), query.getDataset(), new EmptyBindingSet(), false);
try {
while (sparqlResults.hasNext()) {
System.out.println(sparqlResults.next());
}
} finally {
sparqlResults.close();
}
Graph graph = ((GraphSail) sail).getBaseGraph();
System.out.println();
for (Vertex v : graph.getVertices()) {
System.out.println("------");
System.out.println(v);
for (String key : v.getPropertyKeys()) {
System.out.println(key + "=" + v.getProperty(key));
}
}
for (Edge e : graph.getEdges()) {
System.out.println("------");
System.out.println(e);
for (String key : e.getPropertyKeys()) {
System.out.println(key + "=" + e.getProperty(key));
}
}
} finally {
sc.rollback();
sc.close();
}
} finally {
sail.shutDown();
}
}
////////////////////////////////////////////////////////////////////////////////
private void assertTriplePattern(final String pattern, final boolean isValid) {
boolean m = GraphSail.INDEX_PATTERN.matcher(pattern).matches();
assertTrue(isValid ? m : !m);
}
private int countVertices() {
int count = 0;
for (Vertex v : graph.getVertices()) {
count++;
}
return count;
}
private int countEdges() {
int count = 0;
for (Edge e : graph.getEdges()) {
count++;
}
return count;
}
protected static void deleteDirectory(final File directory) {
if (directory.exists()) {
for (File file : directory.listFiles()) {
if (file.isDirectory()) {
deleteDirectory(file);
} else {
file.delete();
}
}
directory.delete();
}
}
protected File computeTestDataRoot() {
final String clsUri = this.getClass().getName().replace('.', '/') + ".class";
final URL url = this.getClass().getClassLoader().getResource(clsUri);
final String clsPath = url.getPath();
final File root = new File(clsPath.substring(0, clsPath.length() - clsUri.length()));
return new File(root.getParentFile(), "test-data");
}
}