Package com.tinkerpop.blueprints.oupls.sail

Source Code of com.tinkerpop.blueprints.oupls.sail.SailTest

package com.tinkerpop.blueprints.oupls.sail;

import info.aduna.iteration.CloseableIteration;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openrdf.model.BNode;
import org.openrdf.model.Literal;
import org.openrdf.model.Namespace;
import org.openrdf.model.Resource;
import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.model.ValueFactory;
import org.openrdf.model.datatypes.XMLDatatypeUtil;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.model.vocabulary.RDFS;
import org.openrdf.model.vocabulary.XMLSchema;
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.rio.RDFHandler;
import org.openrdf.rio.RDFHandlerException;
import org.openrdf.rio.RDFParser;
import org.openrdf.rio.Rio;
import org.openrdf.sail.NotifyingSail;
import org.openrdf.sail.NotifyingSailConnection;
import org.openrdf.sail.Sail;
import org.openrdf.sail.SailChangedEvent;
import org.openrdf.sail.SailChangedListener;
import org.openrdf.sail.SailConnection;
import org.openrdf.sail.SailConnectionListener;
import org.openrdf.sail.SailException;
import org.openrdf.sail.inferencer.InferencerConnection;
import org.openrdf.sail.inferencer.fc.ForwardChainingRDFSInferencer;

import javax.xml.datatype.XMLGregorianCalendar;
import java.io.Closeable;
import java.io.InputStream;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;

import static junit.framework.Assert.*;

/**
* @author Joshua Shinavier (http://fortytwo.net)
*/
public abstract class SailTest {
    protected Sail sail = null;
    protected ForwardChainingRDFSInferencer inferencer;

    protected boolean uniqueStatements = false;

    @Before
    public final void setUp() throws Exception {
        before();
        this.sail = createSail();
        sail.initialize();

        if (sail instanceof NotifyingSail) {
            SailConnection sc = sail.getConnection();
            try {
                if (sc instanceof InferencerConnection) {
                    inferencer = new ForwardChainingRDFSInferencer((NotifyingSail) sail);
                }
            } finally {
                sc.rollback();
                sc.close();
            }
        }

        addFile(SailTest.class.getResourceAsStream("graph-example-sail-test.trig"), RDFFormat.TRIG);
    }

    @After
    public final void tearDown() throws Exception {
        sail.shutDown();
        after();
    }

    protected abstract void before() throws Exception;

    protected abstract void after() throws Exception;

    protected abstract Sail createSail() throws Exception;

    // statement manipulation //////////////////////////////////////////////////

    @Test
    public void testGetStatementsS_POG() throws Exception {
        SailConnection sc = sail.getConnection();
        try {
            sc.begin();
            URI uriA = sail.getValueFactory().createURI("http://example.org/test/S_POG#a");
            URI uriB = sail.getValueFactory().createURI("http://example.org/test/S_POG#b");
            URI uriC = sail.getValueFactory().createURI("http://example.org/test/S_POG#c");
            URI uriD = sail.getValueFactory().createURI("http://example.org/test/S_POG#d");
            int before, after;

            // default context, different S,P,O
            sc.removeStatements(uriA, null, null);
            sc.commit();
            sc.begin();
            before = countStatements(sc, uriA, null, null, false);
            sc.addStatement(uriA, uriB, uriC);
            sc.commit();
            sc.begin();
            after = countStatements(sc, uriA, null, null, false);
            assertEquals(0, before);
            System.out.flush();
            assertEquals(1, after);

            // one specific context, different S,P,O
            sc.removeStatements(uriA, null, null, uriD);
            sc.commit();
            sc.begin();
            before = countStatements(sc, uriA, null, null, false, uriD);
            sc.addStatement(uriA, uriB, uriC, uriD);
            sc.commit();
            sc.begin();
            after = countStatements(sc, uriA, null, null, false, uriD);
            assertEquals(0, before);
            assertEquals(1, after);

            // one specific context, same S,P,O,G
            sc.removeStatements(uriA, null, null, uriA);
            sc.commit();
            sc.begin();
            before = countStatements(sc, uriA, null, null, false, uriA);
            sc.addStatement(uriA, uriB, uriC, uriA);
            sc.commit();
            sc.begin();
            after = countStatements(sc, uriA, null, null, false, uriA);
            assertEquals(0, before);
            assertEquals(1, after);

            // default context, same S,P,O
            sc.removeStatements(uriA, null, null);
            sc.commit();
            sc.begin();
            before = countStatements(sc, uriA, null, null, false);
            sc.addStatement(uriA, uriB, uriC);
            sc.commit();
            sc.begin();
            after = countStatements(sc, uriA, null, null, false);
            assertEquals(0, before);
            assertEquals(1, after);
        } finally {
            sc.rollback();
            sc.close();
        }
    }

    @Test
    public void testGetStatementsSP_OG() throws Exception {
        SailConnection sc = sail.getConnection();
        try {
            sc.begin();
            URI uriA = sail.getValueFactory().createURI("http://example.org/test/SP_OG#a");
            URI uriB = sail.getValueFactory().createURI("http://example.org/test/SP_OG#b");
            URI uriC = sail.getValueFactory().createURI("http://example.org/test/SP_OG#c");
            int before, after;

            // Add statement to the implicit null context.
            sc.removeStatements(null, null, null);
            before = countStatements(sc, uriA, uriB, null, false);
            sc.addStatement(uriA, uriB, uriC);
            sc.commit();
            sc.begin();
            after = countStatements(sc, uriA, uriB, null, false);
            assertEquals(0, before);
            assertEquals(1, after);
        } finally {
            sc.rollback();
            sc.close();
        }
    }

    @Test
    public void testGetStatementsO_SPG() throws Exception {
        SailConnection sc = sail.getConnection();
        try {
            sc.begin();
            URI uriA = sail.getValueFactory().createURI("http://example.org/test/O_SPG#a");
            URI uriB = sail.getValueFactory().createURI("http://example.org/test/O_SPG#b");
            URI uriC = sail.getValueFactory().createURI("http://example.org/test/O_SPG#c");
            Literal plainLitA = sail.getValueFactory().createLiteral("arbitrary plain literal 9548734867");
            Literal stringLitA = sail.getValueFactory().createLiteral("arbitrary string literal 8765", XMLSchema.STRING);
            int before, after;

            // Add statement to a specific context.
            sc.removeStatements(null, null, uriA, uriA);
            sc.commit();
            sc.begin();
            before = countStatements(sc, null, null, uriA, false);
            sc.addStatement(uriB, uriC, uriA);
            sc.commit();
            sc.begin();
            after = countStatements(sc, null, null, uriA, false);
            assertEquals(0, before);
            assertEquals(1, after);

            // Add plain literal statement to the default context.
            sc.removeStatements(null, null, plainLitA);
            sc.commit();
            sc.begin();
            before = countStatements(sc, null, null, plainLitA, false);
            sc.addStatement(uriA, uriA, plainLitA);
            sc.commit();
            sc.begin();
            after = countStatements(sc, null, null, plainLitA, false);
            assertEquals(0, before);
            assertEquals(1, after);

            // Add string-typed literal statement to the default context.
            sc.removeStatements(null, null, plainLitA);
            sc.commit();
            sc.begin();
            before = countStatements(sc, null, null, stringLitA, false);
            sc.addStatement(uriA, uriA, stringLitA);
            sc.commit();
            sc.begin();
            after = countStatements(sc, null, null, stringLitA, false);
            assertEquals(0, before);
            assertEquals(1, after);
        } finally {
            sc.rollback();
            sc.close();
        }
    }

    @Test
    public void testGetStatementsPO_SG() throws Exception {
        SailConnection sc = sail.getConnection();
        try {
            sc.begin();
            URI uriA = sail.getValueFactory().createURI("http://example.org/test/PO_SG#a");
            URI uriB = sail.getValueFactory().createURI("http://example.org/test/PO_SG#b");
            URI foo = sail.getValueFactory().createURI("http://example.org/ns#foo");
            URI firstName = sail.getValueFactory().createURI("http://example.org/ns#firstName");
            Literal plainLitA = sail.getValueFactory().createLiteral("arbitrary plain literal 8765675");
            Literal fooLabel = sail.getValueFactory().createLiteral("foo", XMLSchema.STRING);
            int before, after;

            // Add statement to the implicit null context.
            sc.removeStatements(null, null, null, uriA);
            sc.commit();
            sc.begin();
            before = countStatements(sc, null, uriA, uriB, false);
            sc.addStatement(uriA, uriA, uriB);
            sc.commit();
            sc.begin();
            after = countStatements(sc, null, uriA, uriB, false);
            assertEquals(0, before);
            assertEquals(1, after);

            // Add plain literal statement to the default context.
            sc.removeStatements(null, null, plainLitA);
            sc.commit();
            sc.begin();
            before = countStatements(sc, null, uriA, plainLitA, false);
            sc.addStatement(uriA, uriA, plainLitA);
            sc.addStatement(uriA, uriB, plainLitA);
            sc.addStatement(uriB, uriB, plainLitA);
            sc.commit();
            sc.begin();
            after = countStatements(sc, null, uriA, plainLitA, false);
            assertEquals(0, before);
            assertEquals(1, after);

            // Add string-typed literal statement to the default context.
            sc.removeStatements(null, null, fooLabel);
            sc.commit();
            sc.begin();
            before = countStatements(sc, null, firstName, fooLabel, false);
            sc.addStatement(foo, firstName, fooLabel);
            sc.commit();
            sc.begin();
            after = countStatements(sc, null, firstName, fooLabel, false);
            assertEquals(0, before);
            assertEquals(1, after);
            assertEquals(foo, toSet(sc.getStatements(null, firstName, fooLabel, false)).iterator().next().getSubject());

        } finally {
            sc.rollback();
            sc.close();
        }
    }

    @Test
    public void testGetStatementsSPO_G() throws Exception {
        SailConnection sc = sail.getConnection();
        try {
            sc.begin();
            URI uriA = sail.getValueFactory().createURI("http://example.org/test/S_POG#a");
            URI uriB = sail.getValueFactory().createURI("http://example.org/test/S_POG#b");
            URI uriC = sail.getValueFactory().createURI("http://example.org/test/S_POG#c");
            URI uriD = sail.getValueFactory().createURI("http://example.org/test/S_POG#d");
            int before, after;

            // default context, different S,P,O
            sc.removeStatements(uriA, null, null);
            sc.commit();
            sc.begin();
            before = countStatements(sc, uriA, uriB, uriC, false);
            sc.addStatement(uriA, uriB, uriC);
            sc.commit();
            sc.begin();
            after = countStatements(sc, uriA, uriB, uriC, false);
            assertEquals(0, before);
            assertEquals(1, after);

            // default context, same S,P,O
            sc.removeStatements(uriA, null, null);
            sc.commit();
            sc.begin();
            before = countStatements(sc, uriA, uriB, uriC, false);
            sc.addStatement(uriA, uriB, uriC);
            sc.commit();
            sc.begin();
            after = countStatements(sc, uriA, uriB, uriC, false);
            assertEquals(0, before);
            assertEquals(1, after);

            // one specific context, different S,P,O
            sc.removeStatements(uriA, null, null, uriD);
            sc.commit();
            sc.begin();
            before = countStatements(sc, uriA, uriB, uriC, false, uriD);
            sc.addStatement(uriA, uriB, uriC, uriD);
            sc.commit();
            sc.begin();
            after = countStatements(sc, uriA, uriB, uriC, false, uriD);
            assertEquals(0, before);
            assertEquals(1, after);

            // one specific context, same S,P,O,G
            sc.removeStatements(uriA, null, null, uriA);
            sc.commit();
            sc.begin();
            before = countStatements(sc, uriA, uriB, uriC, false, uriA);
            sc.addStatement(uriA, uriB, uriC, uriA);
            sc.commit();
            sc.begin();
            after = countStatements(sc, uriA, uriB, uriC, false, uriA);
            assertEquals(0, before);
            assertEquals(1, after);
        } finally {
            sc.rollback();
            sc.close();
        }
    }

    @Test
    public void testGetStatementsP_SOG() throws Exception {
        SailConnection sc = sail.getConnection();
        try {
            sc.begin();
            URI uriA = sail.getValueFactory().createURI("http://example.org/test/P_SOG#a");
            URI uriB = sail.getValueFactory().createURI("http://example.org/test/P_SOG#b");
            URI uriC = sail.getValueFactory().createURI("http://example.org/test/P_SOG#c");
            URI foo = sail.getValueFactory().createURI("http://example.org/ns#foo");
            URI firstName = sail.getValueFactory().createURI("http://example.org/ns#firstName");
            Literal plainLitA = sail.getValueFactory().createLiteral("arbitrary plain literal 238445");
            Literal fooLabel = sail.getValueFactory().createLiteral("foo", XMLSchema.STRING);
            int before, after;

            // Add statement to the implicit null context.
            sc.removeStatements(null, uriA, null);
            sc.commit();
            sc.begin();
            before = countStatements(sc, null, uriA, null, false);
            sc.addStatement(uriB, uriA, uriC);
            sc.commit();
            sc.begin();
            after = countStatements(sc, null, uriA, null, false);
            assertEquals(0, before);
            assertEquals(1, after);

            // Add plain literal statement to the default context.
            sc.removeStatements(null, uriA, null);
            sc.commit();
            sc.begin();
            before = countStatements(sc, null, uriA, null, false);
            sc.addStatement(uriA, uriA, plainLitA);
            sc.addStatement(uriA, uriB, plainLitA);
            sc.addStatement(uriB, uriB, plainLitA);
            sc.commit();
            sc.begin();
            after = countStatements(sc, null, uriA, null, false);
            assertEquals(0, before);
            assertEquals(1, after);

            // Add string-typed literal statement to the default context.
            sc.removeStatements(null, firstName, null);
            sc.commit();
            sc.begin();
            before = countStatements(sc, null, firstName, null, false);
            sc.addStatement(foo, firstName, fooLabel);
            sc.commit();
            sc.begin();
            after = countStatements(sc, null, firstName, null, false);
            assertEquals(0, before);
            assertEquals(1, after);
            assertEquals(foo, toSet(sc.getStatements(null, firstName, null, false)).iterator().next().getSubject());

            // Add statement to a non-null context.
            sc.removeStatements(null, uriA, null);
            sc.commit();
            sc.begin();
            before = countStatements(sc, null, uriA, null, false);
            sc.addStatement(uriB, uriA, uriC, uriA);
            sc.commit();
            sc.begin();
            after = countStatements(sc, null, uriA, null, false);
            assertEquals(0, before);
            assertEquals(1, after);

            sc.removeStatements(null, uriA, null);
            sc.commit();
            sc.begin();
            before = countStatements(sc, null, uriA, null, false);
            sc.addStatement(uriB, uriA, uriC, uriC);
            sc.addStatement(uriC, uriA, uriA, uriA);
            sc.commit();
            sc.begin();
            sc.addStatement(uriA, uriA, uriB, uriB);
            sc.commit();
            sc.begin();
            after = countStatements(sc, null, uriA, null, false);
            assertEquals(0, before);
            assertEquals(3, after);

        } finally {
            sc.rollback();
            sc.close();
        }
    }

    @Test
    public void testGetStatementsWithVariableContexts() throws Exception {
        SailConnection sc = sail.getConnection();
        try {
            sc.begin();
            URI uriA = sail.getValueFactory().createURI("http://example.org/uriA");
            URI uriB = sail.getValueFactory().createURI("http://example.org/uriB");
            URI uriC = sail.getValueFactory().createURI("http://example.org/uriC");
            int count;
            sc.clear();
            //sc.removeStatements(uriA, uriA, uriA);
            sc.commit();
            sc.begin();
            Resource[] contexts = {uriA, null};
            sc.addStatement(uriA, uriB, uriC, contexts);
            sc.commit();
            sc.begin();

            // Get statements from all contexts.
            count = countStatements(sc, uriA, null, null, false);
            assertEquals(2, count);

            // Get statements from a specific partition context.
            count = countStatements(sc, null, null, null, false, uriA);
            assertEquals(1, count);

            // Get statements from the null context.
            Resource[] c = {null};
            count = countStatements(sc, null, null, null, false, c);
            //assertTrue(count > 0);
            assertEquals(1, count);
            int countLast = count;

            // Get statements from more than one context.
            count = countStatements(sc, null, null, null, false, contexts);
            assertEquals(1 + countLast, count);

        } finally {
            sc.rollback();
            sc.close();
        }
    }

    @Test
    public void testRemoveStatements() throws Exception {
        SailConnection sc = sail.getConnection();
        try {
            sc.begin();
            URI uriA = sail.getValueFactory().createURI("http://example.org/uriA");
            URI uriB = sail.getValueFactory().createURI("http://example.org/uriB");
            URI uriC = sail.getValueFactory().createURI("http://example.org/uriC");
            Resource[] contexts = {uriA, null};
            int count;

            // Remove from all contexts.
            sc.removeStatements(uriA, null, null);
            sc.commit();
            sc.begin();
            count = countStatements(sc, uriA, null, null, false);
            assertEquals(0, count);
            sc.addStatement(uriA, uriB, uriC, contexts);
            sc.commit();
            sc.begin();
            count = countStatements(sc, uriA, null, null, false);
            assertEquals(2, count);
            sc.removeStatements(uriA, null, null);
            sc.commit();
            sc.begin();
            count = countStatements(sc, uriA, null, null, false);
            assertEquals(0, count);

            // Remove from one partition context.
            sc.removeStatements(uriA, null, null);
            sc.commit();
            sc.begin();
            count = countStatements(sc, uriA, null, null, false);
            assertEquals(0, count);
            sc.addStatement(uriA, uriB, uriC, contexts);
            sc.commit();
            sc.begin();
            count = countStatements(sc, uriA, null, null, false);
            assertEquals(2, count);
            Resource[] oneContext = {uriA};
            sc.removeStatements(uriA, null, null, oneContext);
            sc.commit();
            sc.begin();
            count = countStatements(sc, uriA, null, null, false);
            assertEquals(1, count);

            // Remove from the null context.
            sc.removeStatements(uriA, null, null);
            sc.commit();
            sc.begin();
            count = countStatements(sc, uriA, null, null, false);
            assertEquals(0, count);
            sc.addStatement(uriA, uriB, uriC, contexts);
            sc.commit();
            sc.begin();
            count = countStatements(sc, uriA, null, null, false);
            assertEquals(2, count);
            Resource[] nullContext = {null};
            sc.removeStatements(uriA, null, null, nullContext);
            sc.commit();
            sc.begin();
            count = countStatements(sc, uriA, null, null, false);
            assertEquals(1, count);

            // Remove from more than one context.
            sc.removeStatements(uriA, null, null);
            sc.commit();
            sc.begin();
            count = countStatements(sc, uriA, null, null, false);
            assertEquals(0, count);
            sc.addStatement(uriA, uriB, uriC, contexts);
            sc.commit();
            sc.begin();
            count = countStatements(sc, uriA, null, null, false);
            assertEquals(2, count);
            sc.removeStatements(uriA, null, null);
            sc.commit();
            sc.begin();
            count = countStatements(sc, uriA, null, null, false, contexts);
            assertEquals(0, count);

        } finally {
            sc.rollback();
            sc.close();
        }
    }

    @Test
    public void testClear() throws Exception {
        URI uriA = sail.getValueFactory().createURI("http://example.org/uriA");
        URI uriB = sail.getValueFactory().createURI("http://example.org/uriB");
        URI uriC = sail.getValueFactory().createURI("http://example.org/uriC");

        SailConnection sc = sail.getConnection();
        try {
            sc.begin();
            sc.clear();
            assertEquals(0L, sc.size());
            sc.addStatement(uriA, uriB, uriC, uriA);
            sc.addStatement(uriC, uriA, uriB, uriA);
            sc.addStatement(uriB, uriC, uriA, uriA);
            assertEquals(3L, sc.size(uriA));
            sc.addStatement(uriA, uriB, uriC, uriB);
            sc.addStatement(uriB, uriC, uriA, uriB);
            assertEquals(2L, sc.size(uriB));
            sc.addStatement(uriA, uriB, uriC);
            assertEquals(1L, sc.size((Resource) null));
            sc.addStatement(uriA, uriB, uriC, uriC);
            sc.addStatement(uriB, uriC, uriA, uriC);
            sc.addStatement(uriC, uriA, uriB, uriC);
            sc.addStatement(uriA, uriB, uriB, uriC);
            assertEquals(4L, sc.size(uriC));
            assertEquals(10L, sc.size());
            sc.clear(uriA, uriC);
            assertEquals(1L, sc.size((Resource) null));
            assertEquals(0L, sc.size(uriA));
            assertEquals(2L, sc.size(uriB));
            assertEquals(0L, sc.size(uriC));
            assertEquals(3L, sc.size());
            sc.clear();
            assertEquals(0L, sc.size());
            sc.commit();
        } finally {
            sc.rollback();
            sc.close();
        }
    }

    @Test
    public void testGetContextIDs() throws Exception {
        URI uriA = sail.getValueFactory().createURI("http://example.org/uriA");
        URI uriB = sail.getValueFactory().createURI("http://example.org/uriB");
        URI uriC = sail.getValueFactory().createURI("http://example.org/uriC");
        URI uriD = sail.getValueFactory().createURI("http://example.org/uriD");

        SailConnection sc = sail.getConnection();
        try {
            sc.begin();
            sc.clear();

            sc.addStatement(uriA, uriB, uriC);
            assertEquals(1, countStatements(sc, null, null, null, false));
            assertEquals(0, count(sc.getContextIDs()));

            sc.addStatement(uriC, uriB, uriA, uriC);
            assertEquals(2, countStatements(sc, null, null, null, false));
            assertEquals(1, count(sc.getContextIDs()));
            assertEquals(uriC, sc.getContextIDs().next());

            sc.addStatement(uriD, uriB, uriA, uriC);
            assertEquals(3, countStatements(sc, null, null, null, false));
            assertEquals(1, count(sc.getContextIDs()));
        } finally {
            sc.rollback();
            sc.close();
        }
    }

    @Test
    public void testSize() throws Exception {
        URI uriA = sail.getValueFactory().createURI("http://example.org/uriA");
        URI uriB = sail.getValueFactory().createURI("http://example.org/uriB");
        URI uriC = sail.getValueFactory().createURI("http://example.org/uriC");

        SailConnection sc = sail.getConnection();
        try {
            sc.begin();
            sc.removeStatements(null, null, null);

            assertEquals(0L, sc.size());
            sc.addStatement(uriA, uriB, uriC, uriA);
            // sc.commit();
            assertEquals(1L, sc.size());
            sc.addStatement(uriA, uriB, uriC, uriB);
            // sc.commit();
            assertEquals(2L, sc.size());
            sc.addStatement(uriB, uriB, uriC, uriB);
            // sc.commit();
            assertEquals(3L, sc.size());
            sc.addStatement(uriC, uriB, uriA);
            // sc.commit();
            assertEquals(4L, sc.size());
            assertEquals(1L, sc.size(uriA));
            assertEquals(2L, sc.size(uriB));
            assertEquals(0L, sc.size(uriC));
            assertEquals(1L, sc.size((URI) null));
            assertEquals(3L, sc.size(uriB, null));
            assertEquals(3L, sc.size(uriB, uriC, null));
            assertEquals(4L, sc.size(uriA, uriB, null));
            assertEquals(4L, sc.size(uriA, uriB, uriC, null));
            assertEquals(3L, sc.size(uriA, uriB));
            sc.commit();
        } finally {
            sc.rollback();
            sc.close();
        }
    }

    @Test
    public void testDuplicateStatements() throws Exception {
        if (uniqueStatements) {
            URI uriA = sail.getValueFactory().createURI("http://example.org/uriA");
            URI uriB = sail.getValueFactory().createURI("http://example.org/uriB");
            URI uriC = sail.getValueFactory().createURI("http://example.org/uriC");
            SailConnection sc = sail.getConnection();
            try {
                sc.begin();
                sc.clear();
                assertEquals(0, countStatements(sc, uriA, uriB, uriC, false));
                sc.addStatement(uriA, uriB, uriC);
                assertEquals(1, countStatements(sc, uriA, uriB, uriC, false));
                sc.addStatement(uriA, uriB, uriC);
                assertEquals(1, countStatements(sc, uriA, uriB, uriC, false));

                sc.addStatement(uriA, uriB, uriC, uriC);
                assertEquals(2, countStatements(sc, uriA, uriB, uriC, false));
                assertEquals(1, countStatements(sc, uriA, uriB, uriC, false, uriC));
                sc.commit();
            } finally {
                sc.rollback();
                sc.close();
            }
        }
    }

    // URIs ////////////////////////////////////////////////////////////////////

    // literals ////////////////////////////////////////////////////////////////

    // Note: this test will always pass as long as we're using ValueFactoryImpl

    @Test
    public void testCreateLiteralsThroughValueFactory() throws Exception {
        Literal l;
        ValueFactory vf = sail.getValueFactory();

        l = vf.createLiteral("a plain literal");
        assertNotNull(l);
        assertNull(l.getLanguage());
        assertEquals("a plain literal", l.getLabel());
        assertNull(l.getDatatype());
        l = vf.createLiteral("auf Deutsch, bitte", "de");
        assertNotNull(l);
        assertEquals("de", l.getLanguage());
        assertEquals("auf Deutsch, bitte", l.getLabel());
        assertNull(l.getDatatype());

        // Test data-typed createLiteral methods
        l = vf.createLiteral("foo", XMLSchema.STRING);
        assertNotNull(l);
        assertNull(l.getLanguage());
        assertEquals("foo", l.getLabel());
        assertEquals(XMLSchema.STRING, l.getDatatype());
        l = vf.createLiteral(42);
        assertNotNull(l);
        assertNull(l.getLanguage());
        assertEquals("42", l.getLabel());
        assertEquals(42, l.intValue());
        assertEquals(XMLSchema.INT, l.getDatatype());
        l = vf.createLiteral(42l);
        assertNotNull(l);
        assertNull(l.getLanguage());
        assertEquals("42", l.getLabel());
        assertEquals(42l, l.longValue());
        assertEquals(XMLSchema.LONG, l.getDatatype());
        l = vf.createLiteral((short) 42);
        assertNotNull(l);
        assertNull(l.getLanguage());
        assertEquals("42", l.getLabel());
        assertEquals((short) 42, l.shortValue());
        assertEquals(XMLSchema.SHORT, l.getDatatype());
        l = vf.createLiteral(true);
        assertNotNull(l);
        assertNull(l.getLanguage());
        assertEquals("true", l.getLabel());
        assertEquals(true, l.booleanValue());
        assertEquals(XMLSchema.BOOLEAN, l.getDatatype());
        l = vf.createLiteral((byte) 'c');
        assertNotNull(l);
        assertNull(l.getLanguage());
        assertEquals("99", l.getLabel());
        assertEquals((byte) 'c', l.byteValue());
        assertEquals(XMLSchema.BYTE, l.getDatatype());
        XMLGregorianCalendar calendar = XMLDatatypeUtil.parseCalendar("2002-10-10T12:00:00-05:00");
        l = vf.createLiteral(calendar);
        assertNotNull(l);
        assertNull(l.getLanguage());
        assertEquals("2002-10-10T12:00:00-05:00", l.getLabel());
        assertEquals(calendar, l.calendarValue());
        assertEquals(XMLSchema.DATETIME, l.getDatatype());
    }

    @Test
    public void testGetLiteralsFromTripleStore() throws Exception {
        Literal l;
        String prefix = "urn:com.tinkerpop.blueprints.pgm.oupls.sail.test/";
        XMLGregorianCalendar calendar;
        ValueFactory vf = sail.getValueFactory();
        SailConnection sc = sail.getConnection();

        // Get an actual plain literal from the triple store.
        URI ford = vf.createURI(prefix + "ford");
        l = (Literal) toSet(sc.getStatements(ford, RDFS.COMMENT, null, false)).iterator().next().getObject();
        assertNotNull(l);
        assertNull(l.getLanguage());
        assertEquals("he really knows where his towel is", l.getLabel());
        assertNull(l.getDatatype());
        URI thor = vf.createURI(prefix + "thor");

        // Get an actual language-tagged literal from the triple store.
        URI foafName = vf.createURI("http://xmlns.com/foaf/0.1/name");
        Iterator<Statement> iter = toSet(sc.getStatements(thor, foafName, null, false)).iterator();
        boolean found = false;
        while (iter.hasNext()) {
            l = (Literal) iter.next().getObject();
            if (l.getLanguage().equals("en")) {
                found = true;
                assertEquals("Thor", l.getLabel());
                assertNull(l.getDatatype());
            }
            // if (l.getLanguage().equals("is")) {
            // found = true;
            // assertEquals("?�r", l.getLabel());
            // }
        }
        assertTrue(found);

        // Get an actual data-typed literal from the triple-store.
        URI msnChatID = vf.createURI("http://xmlns.com/foaf/0.1/msnChatID");
        l = (Literal) toSet(sc.getStatements(thor, msnChatID, null, false)).iterator().next().getObject();
        assertNotNull(l);
        assertNull(l.getLanguage());
        assertEquals("Thorster123", l.getLabel());
        assertEquals(XMLSchema.STRING, l.getDatatype());

        // Test Literal.xxxValue() methods for Literals read from the triple
        // store
        URI valueUri, hasValueUri;
        hasValueUri = vf.createURI(prefix + "hasValue");
        valueUri = vf.createURI(prefix + "stringValue");
        l = (Literal) toSet(sc.getStatements(valueUri, hasValueUri, null, false)).iterator().next().getObject();
        assertNotNull(l);
        assertNull(l.getLanguage());
        assertEquals("foo", l.getLabel());
        assertEquals(XMLSchema.STRING, l.getDatatype());
        valueUri = vf.createURI(prefix + "byteValue");
        l = (Literal) toSet(sc.getStatements(valueUri, hasValueUri, null, false)).iterator().next().getObject();
        assertNotNull(l);
        assertNull(l.getLanguage());
        assertEquals("99", l.getLabel());
        assertEquals(XMLSchema.BYTE, l.getDatatype());
        assertEquals((byte) 'c', l.byteValue());
        valueUri = vf.createURI(prefix + "booleanValue");
        l = (Literal) toSet(sc.getStatements(valueUri, hasValueUri, null, false)).iterator().next().getObject();
        assertNotNull(l);
        assertNull(l.getLanguage());
        assertEquals("false", l.getLabel());
        assertEquals(XMLSchema.BOOLEAN, l.getDatatype());
        assertEquals(false, l.booleanValue());
        valueUri = vf.createURI(prefix + "intValue");
        l = (Literal) toSet(sc.getStatements(valueUri, hasValueUri, null, false)).iterator().next().getObject();
        assertNotNull(l);
        assertNull(l.getLanguage());
        assertEquals("42", l.getLabel());
        assertEquals(XMLSchema.INT, l.getDatatype());
        assertEquals(42, l.intValue());
        valueUri = vf.createURI(prefix + "shortValue");
        l = (Literal) toSet(sc.getStatements(valueUri, hasValueUri, null, false)).iterator().next().getObject();
        assertNotNull(l);
        assertNull(l.getLanguage());
        assertEquals("42", l.getLabel());
        assertEquals(XMLSchema.SHORT, l.getDatatype());
        assertEquals((short) 42, l.shortValue());
        valueUri = vf.createURI(prefix + "longValue");
        l = (Literal) toSet(sc.getStatements(valueUri, hasValueUri, null, false)).iterator().next().getObject();
        assertNotNull(l);
        assertNull(l.getLanguage());
        assertEquals("42", l.getLabel());
        assertEquals(XMLSchema.LONG, l.getDatatype());
        assertEquals(42l, l.longValue());
        valueUri = vf.createURI(prefix + "floatValue");
        l = (Literal) toSet(sc.getStatements(valueUri, hasValueUri, null, false)).iterator().next().getObject();
        assertNotNull(l);
        assertNull(l.getLanguage());
        assertEquals("3.1415926", l.getLabel());
        assertEquals(XMLSchema.FLOAT, l.getDatatype());
        assertEquals((float) 3.1415926, l.floatValue());
        valueUri = vf.createURI(prefix + "doubleValue");
        l = (Literal) toSet(sc.getStatements(valueUri, hasValueUri, null, false)).iterator().next().getObject();
        assertNotNull(l);
        assertNull(l.getLanguage());
        assertEquals("3.1415926", l.getLabel());
        assertEquals(XMLSchema.DOUBLE, l.getDatatype());
        assertEquals(3.1415926, l.doubleValue());
        valueUri = vf.createURI(prefix + "dateTimeValue");
        calendar = XMLDatatypeUtil.parseCalendar("2002-10-10T12:00:00-05:00");
        l = (Literal) toSet(sc.getStatements(valueUri, hasValueUri, null, false)).iterator().next().getObject();
        assertNotNull(l);
        assertNull(l.getLanguage());
        assertEquals("2002-10-10T12:00:00-05:00", l.getLabel());
        assertEquals(XMLSchema.DATETIME, l.getDatatype());
        assertEquals(calendar, l.calendarValue());
        sc.rollback();
        sc.close();
    }

    // blank nodes /////////////////////////////////////////////////////////////

    @Test
    public void testBlankNodes() throws Throwable {
        URI uriA = sail.getValueFactory().createURI("http://example.org/test/S_POG#a");
        URI uriB = sail.getValueFactory().createURI("http://example.org/test/S_POG#b");
        SailConnection sc = sail.getConnection();
        try {
            sc.begin();
            ValueFactory factory = sail.getValueFactory();
            BNode bNode = factory.createBNode();
            try {
                sc.addStatement(uriA, uriA, bNode);
            } catch (SailException se) {
                // FIXME: not supporting blank nodes ATM
                assertTrue(se.getCause() instanceof UnsupportedOperationException);
            }
            sc.commit();
        } finally {
            sc.rollback();
            sc.close();
        }
    }

    // tuple queries ///////////////////////////////////////////////////////////

    @Test
    public void testEvaluate() throws Exception {
        Set<String> languages;
        String prefix = "urn:com.tinkerpop.blueprints.pgm.oupls.sail.test/";
        URI thorUri = sail.getValueFactory().createURI(prefix + "thor");

        SailConnection sc = sail.getConnection();
        try {
            sc.begin();
            URI uriA = sail.getValueFactory().createURI("http://example.org/uriA");
            URI uriB = sail.getValueFactory().createURI("http://example.org/uriB");
            URI uriC = sail.getValueFactory().createURI("http://example.org/uriC");
            sc.addStatement(uriA, uriB, uriC);
            sc.commit();
            sc.begin();

            SPARQLParser parser = new SPARQLParser();
            BindingSet bindings = new EmptyBindingSet();
            String baseURI = "http://example.org/bogus/";
            String queryStr;
            ParsedQuery query;
            CloseableIteration<? extends BindingSet, QueryEvaluationException> results;
            int count;
            // s ?p ?o SELECT
            queryStr = "SELECT ?y ?z WHERE { <http://example.org/uriA> ?y ?z }";
            query = parser.parseQuery(queryStr, baseURI);
            results = sc.evaluate(query.getTupleExpr(), query.getDataset(), bindings, false);
            count = 0;
            while (results.hasNext()) {
                count++;
                BindingSet set = results.next();
                URI y = (URI) set.getValue("y");
                Value z = (Value) set.getValue("z");
                assertNotNull(y);
                assertNotNull(z);
                // System.out.println("y = " + y + ", z = " + z);
            }
            results.close();
            assertTrue(count > 0);

            // s p ?o SELECT using a namespace prefix
            queryStr = "PREFIX foaf: <http://xmlns.com/foaf/0.1/>\n" + "SELECT ?z WHERE { <" + prefix + "thor> foaf:name ?z }";
            query = parser.parseQuery(queryStr, baseURI);
            results = sc.evaluate(query.getTupleExpr(), query.getDataset(), bindings, false);
            count = 0;
            languages = new HashSet<String>();
            while (results.hasNext()) {
                count++;
                BindingSet set = results.next();
                Literal z = (Literal) set.getValue("z");
                assertNotNull(z);
                languages.add(z.getLanguage());
            }
            results.close();
            assertTrue(count > 0);
            assertEquals(2, languages.size());
            assertTrue(languages.contains("en"));
            assertTrue(languages.contains("is"));

            // ?s p o SELECT using a plain literal value with no language tag
            queryStr = "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n" + "SELECT ?s WHERE { ?s rdfs:comment \"he really knows where his towel is\" }";
            URI fordUri = sail.getValueFactory().createURI(prefix + "ford");
            query = parser.parseQuery(queryStr, baseURI);
            results = sc.evaluate(query.getTupleExpr(), query.getDataset(), bindings, false);
            count = 0;
            while (results.hasNext()) {
                count++;
                BindingSet set = results.next();
                URI s = (URI) set.getValue("s");
                assertNotNull(s);
                assertEquals(s, fordUri);
            }
            results.close();
            assertTrue(count > 0);

            // ?s p o SELECT using a language-specific literal value
            queryStr = "PREFIX foaf: <http://xmlns.com/foaf/0.1/>\n" + "SELECT ?s WHERE { ?s foaf:name \"Thor\"@en }";
            query = parser.parseQuery(queryStr, baseURI);
            results = sc.evaluate(query.getTupleExpr(), query.getDataset(), bindings, false);
            count = 0;
            while (results.hasNext()) {
                count++;
                BindingSet set = results.next();
                URI s = (URI) set.getValue("s");
                assertNotNull(s);
                assertEquals(s, thorUri);
            }
            results.close();
            assertTrue(count > 0);

            // The language tag is necessary
            queryStr = "PREFIX foaf: <http://xmlns.com/foaf/0.1/>\n" + "SELECT ?s WHERE { ?s foaf:name \"Thor\" }";
            query = parser.parseQuery(queryStr, baseURI);
            results = sc.evaluate(query.getTupleExpr(), query.getDataset(), bindings, false);
            count = 0;
            while (results.hasNext()) {
                count++;
                results.next();
            }
            results.close();
            assertEquals(0, count);

            // ?s p o SELECT using a typed literal value
            queryStr = "PREFIX foaf: <http://xmlns.com/foaf/0.1/>\n" + "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>\n" + "SELECT ?s WHERE { ?s foaf:msnChatID \"Thorster123\"^^xsd:string }";
            query = parser.parseQuery(queryStr, baseURI);
            results = sc.evaluate(query.getTupleExpr(), query.getDataset(), bindings, false);
            count = 0;
            while (results.hasNext()) {
                count++;
                BindingSet set = results.next();
                URI s = (URI) set.getValue("s");
                assertNotNull(s);
                assertEquals(s, thorUri);
            }
            results.close();
            assertTrue(count > 0);

            // The data type is necessary
            queryStr = "PREFIX foaf: <http://xmlns.com/foaf/0.1/>\n" + "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>\n" + "SELECT ?s WHERE { ?s foaf:msnChatID \"Thorster123\" }";
            query = parser.parseQuery(queryStr, baseURI);
            results = sc.evaluate(query.getTupleExpr(), query.getDataset(), bindings, false);
            count = 0;
            while (results.hasNext()) {
                count++;
                results.next();
            }
            results.close();
            assertEquals(0, count);

            // s ?p o SELECT
            // TODO: commented out languages for now
            queryStr = "PREFIX foaf: <http://xmlns.com/foaf/0.1/>\n" + "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>\n" + "SELECT ?p WHERE { <" + prefix + "thor> ?p \"Thor\"@en }";
            query = parser.parseQuery(queryStr, baseURI);
            URI foafNameUri = sail.getValueFactory().createURI("http://xmlns.com/foaf/0.1/name");
            results = sc.evaluate(query.getTupleExpr(), query.getDataset(), bindings, false);
            count = 0;
            while (results.hasNext()) {
                count++;
                BindingSet set = results.next();
                URI p = (URI) set.getValue("p");
                assertNotNull(p);
                assertEquals(p, foafNameUri);
            }
            results.close();
            assertTrue(count > 0);

            // context-specific SELECT
            queryStr = "PREFIX foaf: <http://xmlns.com/foaf/0.1/>\n" + "SELECT ?z\n" + "FROM <" + prefix + "ctx1>\n" + "WHERE { <" + prefix + "thor> foaf:name ?z }";
            query = parser.parseQuery(queryStr, baseURI);
            results = sc.evaluate(query.getTupleExpr(), query.getDataset(), bindings, false);
            count = 0;
            languages = new HashSet<String>();
            while (results.hasNext()) {
                count++;
                BindingSet set = results.next();
                Literal z = (Literal) set.getValue("z");
                assertNotNull(z);
                languages.add(z.getLanguage());
            }
            results.close();
            assertTrue(count > 0);
            assertEquals(2, languages.size());
            assertTrue(languages.contains("en"));
            assertTrue(languages.contains("is"));
            queryStr = "PREFIX foaf: <http://xmlns.com/foaf/0.1/>\n" + "SELECT ?z\n" + "FROM <http://example.org/emptycontext>\n" + "WHERE { <" + prefix + "thor> foaf:name ?z }";
            query = parser.parseQuery(queryStr, baseURI);
            results = sc.evaluate(query.getTupleExpr(), query.getDataset(), bindings, false);
            count = 0;
            while (results.hasNext()) {
                count++;
                results.next();
            }
            results.close();
            assertEquals(0, count);

            // s p o? select without and with inferencing
            // TODO commented out waiting for inferencing
            // queryStr =
            // "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n"
            // + "SELECT ?o\n"
            // + "WHERE { <" + prefix + "instance1> rdf:type ?o }";
            // query = parser.parseQuery(queryStr, baseURI);
            // results = sc.evaluate(query.getTupleExpr(), query.getDataset(),
            // bindings, false);
            // count = 0;
            // while (results.hasNext()) {
            // count++;
            // BindingSet set = results.next();
            // URI o = (URI) set.getValue("o");
            // assertEquals(prefix + "classB", o.toString());
            // }
            // results.close();
            // assertEquals(1, count);
            // results = sc.evaluate(query.getTupleExpr(), query.getDataset(),
            // bindings, true);
            // count = 0;
            // boolean foundA = false, foundB = false;
            // while (results.hasNext()) {
            // count++;
            // BindingSet set = results.next();
            // URI o = (URI) set.getValue("o");
            // String s = o.toString();
            // if (s.equals(prefix + "classA")) {
            // foundA = true;
            // } else if (s.equals(prefix + "classB")) {
            // foundB = true;
            // }
            // }
            // results.close();
            // assertEquals(2, count);
            // assertTrue(foundA);
            // assertTrue(foundB);

        } finally {
            sc.rollback();
            sc.close();
        }
    }

    @Test
    public void testJoins() throws Exception {
        SPARQLParser parser = new SPARQLParser();
        BindingSet bindings = new EmptyBindingSet();
        String baseURI = "http://example.org/bogus/";

        SailConnection sc = sail.getConnection();
        try {
            CloseableIteration<? extends BindingSet, QueryEvaluationException> results;
            int count;
            String queryStr = "PREFIX : <urn:com.tinkerpop.blueprints.pgm.oupls.sail.test/>\n" +
                    "PREFIX foaf: <http://xmlns.com/foaf/0.1/>\n" +
                    "SELECT ?foaf WHERE {\n" +
                    "    :ford foaf:knows ?friend .\n" +
                    "    ?friend foaf:knows ?foaf .\n" +
                    "}";
            ParsedQuery query = parser.parseQuery(queryStr, baseURI);
            results = sc.evaluate(query.getTupleExpr(), query.getDataset(), bindings, false);
            count = 0;
            while (results.hasNext()) {
                count++;
                BindingSet set = results.next();
                URI foaf = (URI) set.getValue("foaf");
                assertTrue(foaf.stringValue().startsWith("urn:com.tinkerpop.blueprints.pgm.oupls.sail.test/"));
            }
            results.close();
            assertEquals(4, count);
        } finally {
            sc.rollback();
            sc.close();
        }
    }

    // listeners ///////////////////////////////////////////////////////////////
    // (disabled for Sails which do not implement NotifyingSail)

    @Test
    public void testSailConnectionListeners() throws Exception {
        if (sail instanceof NotifyingSail) {
            URI uriA = sail.getValueFactory().createURI("http://example.org/uriA");
            URI uriB = sail.getValueFactory().createURI("http://example.org/uriB");
            URI uriC = sail.getValueFactory().createURI("http://example.org/uriC");

            TestListener listener1 = new TestListener(), listener2 = new TestListener();
            NotifyingSailConnection sc = ((NotifyingSail) sail).getConnection();
            try {
                sc.begin();
                sc.clear();
                sc.commit();
                sc.begin();

                // Add a listener and add statements
                sc.addConnectionListener(listener1);
                sc.addStatement(uriA, uriB, uriC, uriA);
                sc.addStatement(uriB, uriC, uriA, uriA);
                sc.commit();
                sc.begin();

                // Add another listener and remove a statement
                sc.addConnectionListener(listener2);
                sc.removeStatements(uriA, null, null);
                sc.commit();
                sc.begin();

                assertEquals(2, listener1.getAdded());
                assertEquals(0, listener2.getAdded());
                assertEquals(1, listener1.getRemoved());
                assertEquals(1, listener2.getRemoved());

                // Remove a listener and clear
                sc.removeConnectionListener(listener1);
                sc.clear();
                sc.commit();
                sc.begin();

                assertEquals(1, listener1.getRemoved());
                assertEquals(2, listener2.getRemoved());
            } finally {
                sc.rollback();
                sc.close();
            }
        }
    }

    @Test
    public void testSailChangedListeners() throws Exception {
        if (sail instanceof NotifyingSail) {
            final Collection<SailChangedEvent> events = new LinkedList<SailChangedEvent>();
            SailChangedListener listener = new SailChangedListener() {
                public void sailChanged(final SailChangedEvent event) {
                    events.add(event);
                }
            };
            ((NotifyingSail) sail).addSailChangedListener(listener);
            URI uriA = sail.getValueFactory().createURI("http://example.org/uriA");
            URI uriB = sail.getValueFactory().createURI("http://example.org/uriB");
            URI uriC = sail.getValueFactory().createURI("http://example.org/uriC");
            SailConnection sc = sail.getConnection();
            try {
                sc.begin();
                sc.clear();
                sc.commit();
                sc.begin();
                events.clear();
                assertEquals(0, events.size());
                sc.addStatement(uriA, uriB, uriC, uriA);
                sc.addStatement(uriB, uriC, uriA, uriA);
                // Events are buffered until the commit
                assertEquals(0, events.size());
                sc.commit();
                sc.begin();
                // Only one SailChangedEvent per commit
                assertEquals(1, events.size());
                SailChangedEvent event = events.iterator().next();
                assertTrue(event.statementsAdded());
                assertFalse(event.statementsRemoved());
                events.clear();
                assertEquals(0, events.size());
                sc.removeStatements(uriA, uriB, uriC, uriA);
                sc.commit();
                sc.begin();
                assertEquals(1, events.size());
                event = events.iterator().next();
                assertFalse(event.statementsAdded());
                assertTrue(event.statementsRemoved());
                events.clear();
                assertEquals(0, events.size());
                sc.clear();
                sc.commit();
                sc.begin();
                assertEquals(1, events.size());
                event = events.iterator().next();
                assertFalse(event.statementsAdded());
                assertTrue(event.statementsRemoved());
            } finally {
                sc.rollback();
                sc.close();
            }
        }
    }

    // namespaces //////////////////////////////////////////////////////////////

    @Test
    public void testClearNamespaces() throws Exception {
        SailConnection sc = sail.getConnection();
        try {
            CloseableIteration<? extends Namespace, SailException> namespaces;
            int count;
            count = 0;
            namespaces = sc.getNamespaces();
            while (namespaces.hasNext()) {
                namespaces.next();
                count++;
            }
            namespaces.close();
            assertTrue(count > 0);
            // TODO: actually clear namespaces (but this wipes them out for
            // subsequent tests)
        } finally {
            sc.rollback();
            sc.close();
        }
    }

    @Test
    public void testGetNamespace() throws Exception {
        SailConnection sc = sail.getConnection();
        try {
            // FIXME: temporary
            //sc.setNamespace("foo", "http://example.org/foo/");
            //showNamespaces(sc);

            String name;
            name = sc.getNamespace("bogus");
            assertNull(name);
            // assertEquals(name, "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
            name = sc.getNamespace("rdfs");
            //sc.commit();
            assertEquals(name, "http://www.w3.org/2000/01/rdf-schema#");
        } finally {
            sc.rollback();
            sc.close();
        }
    }

    private void showNamespaces(final SailConnection c) throws SailException {
        System.out.println("namespaces:");
        CloseableIteration<? extends Namespace, SailException> iter = c.getNamespaces();
        try {
            while (iter.hasNext()) {
                Namespace n = iter.next();
                System.out.println("\t" + n.getPrefix() + ":\t" + n.getName());
            }
        } finally {
            iter.close();
        }
    }

    @Test
    public void testGetNamespaces() throws Exception {
        SailConnection sc = sail.getConnection();
        try {
            sc.begin();
            CloseableIteration<? extends Namespace, SailException> namespaces;
            int before = 0, during = 0, after = 0;
            // just iterate through all namespaces
            namespaces = sc.getNamespaces();
            while (namespaces.hasNext()) {
                Namespace ns = namespaces.next();
                before++;
                // System.out.println("namespace: " + ns);
            }
            namespaces.close();
            // Note: assumes that these namespace prefixes are unused.
            int nTests = 10;
            String prefixPrefix = "testns";
            String namePrefix = "http://example.org/test";
            for (int i = 0; i < nTests; i++) {
                sc.setNamespace(prefixPrefix + i, namePrefix + i);
            }
            sc.commit();
            sc.begin();
            namespaces = sc.getNamespaces();
            while (namespaces.hasNext()) {
                Namespace ns = namespaces.next();
                during++;
                String prefix = ns.getPrefix();
                String name = ns.getName();
                if (prefix.startsWith(prefixPrefix)) {
                    assertEquals(name, namePrefix + prefix.substring(prefixPrefix.length()));
                }
            }
            namespaces.close();
            for (int i = 0; i < nTests; i++) {
                sc.removeNamespace(prefixPrefix + i);
            }
            sc.commit();
            sc.begin();
            namespaces = sc.getNamespaces();
            while (namespaces.hasNext()) {
                namespaces.next();
                after++;
            }
            namespaces.close();
            assertEquals(during, before + nTests);
            assertEquals(after, before);
        } finally {
            sc.rollback();
            sc.close();
        }
    }

    @Test
    public void testSetNamespace() throws Exception {
        SailConnection sc = sail.getConnection();
        try {
            sc.begin();
            String prefix = "foo";
            String emptyPrefix = "";
            String name = "http://example.org/foo";
            String otherName = "http://example.org/bar";

            sc.removeNamespace(prefix);
            sc.removeNamespace(emptyPrefix);
            sc.commit();
            sc.begin();

            // Namespace initially absent?
            assertNull(sc.getNamespace(prefix));
            assertNull(sc.getNamespace(emptyPrefix));

            // Can we set the namespace?
            sc.setNamespace(prefix, name);
            sc.commit();
            sc.begin();
            assertEquals(sc.getNamespace(prefix), name);

            // Can we reset the namespace?
            sc.setNamespace(prefix, otherName);
            sc.commit();
            sc.begin();
            assertEquals(sc.getNamespace(prefix), otherName);

            // Can we use an empty namespace prefix?
            sc.setNamespace(emptyPrefix, name);
            sc.commit();
            sc.begin();
            assertEquals(sc.getNamespace(emptyPrefix), name);
        } finally {
            sc.rollback();
            sc.close();
        }
    }

    @Test
    public void testRemoveNamespace() throws Exception {
        SailConnection sc = sail.getConnection();
        try {
            sc.begin();
            String prefix = "foo";
            String emptyPrefix = "";
            String name = "http://example.org/foo";

            // Set namespace initially.
            sc.setNamespace(prefix, name);
            sc.commit();
            sc.begin();
            assertEquals(sc.getNamespace(prefix), name);

            // Remove the namespace and make sure it's gone.
            sc.removeNamespace(prefix);
            sc.commit();
            sc.begin();
            assertNull(sc.getNamespace(prefix));

            // Same thing for the default namespace.
            sc.setNamespace(emptyPrefix, name);
            sc.commit();
            sc.begin();
            assertEquals(sc.getNamespace(emptyPrefix), name);
            sc.removeNamespace(emptyPrefix);
            sc.commit();
            sc.begin();
            assertNull(sc.getNamespace(emptyPrefix));
        } finally {
            sc.rollback();
            sc.close();
        }
    }

    // connections and transactions ////////////////////////////////////////////

    @Test
    public void testPersistentCommits() throws Exception {
        SailConnection sc;
        int count;
        URI uriA = sail.getValueFactory().createURI("http://example.org/test/persistentCommits#a");
        URI uriB = sail.getValueFactory().createURI("http://example.org/test/persistentCommits#b");
        URI uriC = sail.getValueFactory().createURI("http://example.org/test/persistentCommits#c");
        sc = sail.getConnection();
        try {
            sc.begin();
            count = countStatements(sc, uriA, null, null, false);
            assertEquals(0, count);
            sc.rollback();
            sc.close();

            sc = sail.getConnection();
            sc.begin();
            sc.addStatement(uriA, uriB, uriC);
            count = countStatements(sc, uriA, null, null, false);
            assertEquals(1, count);
            sc.commit();
            sc.close();

            sc = sail.getConnection();
            sc.begin();
            count = countStatements(sc, uriA, null, null, false);
            assertEquals(1, count);
            sc.rollback();
            sc.close();

            sc = sail.getConnection();
            sc.begin();
            sc.removeStatements(uriA, null, null);
            count = countStatements(sc, uriA, null, null, false);
            assertEquals(0, count);
            sc.commit();
            sc.close();

            sc = sail.getConnection();
            sc.begin();
            count = countStatements(sc, uriA, null, null, false);
            assertEquals(0, count);
        } finally {
            sc.rollback();
            sc.close();
        }
    }

    /*
    // TODO: restore me... but only for ACID-compliant stores
    @Ignore
    @Test
    public void testVisibilityOfChanges() throws Exception {
        SailConnection sc1, sc2;
        int count;
        URI uriA = sail.getValueFactory().createURI(
                "http://example.org/test/visibilityOfChanges#a");
        sc1 = sail.getConnection();
        sc2 = sail.getConnection();
        try {
            sc1.clear();
            sc2.clear();

            // Statement doesn't exist for either connection.
            count = countStatements(sc1, uriA, null, null);
            assertEquals(0, count);
            count = countStatements(sc2, uriA, null, null);
            assertEquals(0, count);
            // First connection adds a statement. It is visible to the first
            // connection, but not to the second.
            sc1.addStatement(uriA, uriA, uriA);
            count = countStatements(sc1, null, null, null);
            assertEquals(1, count);
            count = countStatements(sc2, uriA, null, null);
            assertEquals(0, count);
            // ...
        }
        finally {
            sc2.close();
            sc1.close();
        }
    }
    */

    @Test
    public void testNullContext() throws Exception {
        URI uriA = sail.getValueFactory().createURI("http://example.org/test/nullContext#a");
        URI uriB = sail.getValueFactory().createURI("http://example.org/test/nullContext#b");
        URI uriC = sail.getValueFactory().createURI("http://example.org/test/nullContext#c");
        int count = 0;

        SailConnection sc = sail.getConnection();
        try {
            sc.begin();
            count = countStatements(sc, uriA, null, null, false);
            assertEquals(0, count);
            sc.addStatement(uriA, uriB, uriC);
            Statement statement = sc.getStatements(uriA, uriB, uriC, false, new Resource[]{null}).next();
            Resource context = statement.getContext();
            assertNull(context);
            sc.removeStatements(uriA, null, null);
            sc.commit();
        } finally {
            sc.rollback();
            sc.close();
        }
    }

    // inference ////////////////////////////////////////////////////////////////

    public void testInference() throws Exception {
        if (null != inferencer) {
            URI uriA = sail.getValueFactory().createURI("http://example.org/uriA");
            URI uriB = sail.getValueFactory().createURI("http://example.org/uriB");
            URI classX = sail.getValueFactory().createURI("http://example.org/classX");
            URI classY = sail.getValueFactory().createURI("http://example.org/classY");

            SailConnection sc = inferencer.getConnection();
            try {
                sc.clear();

                sc.addStatement(classX, RDFS.SUBCLASSOF, classY);
                sc.addStatement(uriA, RDF.TYPE, classX);
                sc.addStatement(uriB, RDF.TYPE, classY);
                sc.commit();

                //showStatements(sc, uriA, RDF.TYPE, null);

                assertEquals(3, countStatements(sc, uriA, RDF.TYPE, null, true));
                assertEquals(1, countStatements(sc, uriA, RDF.TYPE, null, false));
                assertEquals(2, countStatements(sc, uriB, RDF.TYPE, null, true));
                assertEquals(1, countStatements(sc, uriB, RDF.TYPE, null, false));

                if (uniqueStatements) {
                    sc.addStatement(uriA, RDF.TYPE, classY);
                    sc.commit();

                    //showStatements(sc, uriA, RDF.TYPE, null);
                    assertEquals(3, countStatements(sc, uriA, RDF.TYPE, null, true));
                    assertEquals(2, countStatements(sc, uriA, RDF.TYPE, null, false));

                    sc.removeStatements(uriA, RDF.TYPE, classY);
                    sc.commit();

                    assertEquals(3, countStatements(sc, uriA, RDF.TYPE, null, true));
                    assertEquals(2, countStatements(sc, uriA, RDF.TYPE, null, false));

                    //sc.removeStatements(uriA, RDF.TYPE, classX);
                    //sc.commit();
                    //assertEquals(1, countStatements(sc, uriA, RDF.TYPE, null));
                }
            } finally {
                sc.rollback();
                sc.close();
            }
        }
    }

// TODO: concurrency testing ///////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////

    private class TestListener implements SailConnectionListener {
        private int added = 0, removed = 0;

        public void statementAdded(final Statement statement) {
            added++;
        }

        public void statementRemoved(final Statement statement) {
            removed++;
        }

        public int getAdded() {
            return added;
        }

        public int getRemoved() {
            return removed;
        }
    }

    protected void showStatements(final SailConnection sc,
                                  final Resource subject,
                                  final URI predicate,
                                  final Value object,
                                  final Resource... contexts) throws SailException {
        CloseableIteration<?, SailException> statements = sc.getStatements(subject, predicate, object, true, contexts);
        int count = 0;
        try {
            while (statements.hasNext()) {
                System.out.println("" + count + ") " + statements.next());
                count++;
            }
        } finally {
            statements.close();
        }
    }

    private <E, X extends Exception> int count(final CloseableIteration<E, X> iter) throws X {
        int c = 0;

        try {
            while (iter.hasNext()) {
                c++;
                iter.next();
            }
        } finally {
            iter.close();
        }

        return c;
    }

    protected int countStatements(final SailConnection sc,
                                  final Resource subject,
                                  final URI predicate,
                                  final Value object,
                                  final boolean includeInferred,
                                  final Resource... contexts) throws SailException {
        CloseableIteration<?, SailException> statements = sc.getStatements(subject, predicate, object, includeInferred, contexts);
        int count = 0;
        try {
            while (statements.hasNext()) {
                statements.next();
                count++;
            }
        } finally {
            statements.close();
        }
        return count;
    }

    private Set<Statement> toSet(final CloseableIteration<? extends Statement, SailException> i) throws SailException {
        try {
            Set<Statement> set = new HashSet<Statement>();
            while (i.hasNext()) {
                set.add(i.next());
            }
            return set;
        } finally {
            i.close();
        }
    }

    protected void clear() throws Exception {
        SailConnection sc = sail.getConnection();
        try {
            sc.begin();
            sc.clear();
            sc.commit();
        } finally {
            sc.rollback();
            sc.close();
        }
    }

    protected void addFile(final InputStream in,
                           final RDFFormat format) throws Exception {
        try {
            SailConnection sc = sail.getConnection();
            sc.begin();
            try {
                RDFHandler h = new SailAdder(sc);
                RDFParser p = Rio.createParser(format);
                p.setRDFHandler(h);
                p.parse(in, "http://example.org/bogusBaseURI/");
                sc.commit();
            } finally {
                sc.rollback();
                sc.close();
            }
        } finally {
            in.close();
        }
    }

    protected class SailAdder implements RDFHandler {
        private final SailConnection c;
        private final Resource[] contexts;

        public SailAdder(final SailConnection c,
                         final Resource... contexts) {
            this.c = c;
            this.contexts = contexts;
        }

        public void startRDF() throws RDFHandlerException {
        }

        public void endRDF() throws RDFHandlerException {
        }

        public void handleNamespace(final String prefix,
                                    final String uri) throws RDFHandlerException {
            try {
                c.setNamespace(prefix, uri);
            } catch (SailException e) {
                throw new RDFHandlerException(e);
            }
        }

        public void handleStatement(final Statement s) throws RDFHandlerException {
            //System.out.println("adding statement: " + s);
            try {
                if (1 <= contexts.length) {
                    for (Resource x : contexts) {
                        c.addStatement(s.getSubject(), s.getPredicate(), s.getObject(), x);
                    }
                } else {
                    c.addStatement(s.getSubject(), s.getPredicate(), s.getObject(), s.getContext());
                }
            } catch (SailException e) {
                throw new RDFHandlerException(e);
            }
        }

        public void handleComment(String s) throws RDFHandlerException {
        }
    }
}
TOP

Related Classes of com.tinkerpop.blueprints.oupls.sail.SailTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.