Java tutorial
package de.unikiel.inf.comsys.neo4j.inference; /* * #%L * neo4j-sparql-extension * %% * Copyright (C) 2014 Niclas Hoyer * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ import de.unikiel.inf.comsys.neo4j.inference.rules.Rules; import de.unikiel.inf.comsys.neo4j.inference.rules.Rule; import com.google.common.collect.Multiset; import com.google.common.collect.Multisets; import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; import java.util.ArrayList; import java.util.List; import org.apache.commons.io.IOUtils; import org.junit.After; import static org.junit.Assert.*; import org.junit.Before; import org.junit.Test; import org.junit.rules.ErrorCollector; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; import org.openrdf.model.ValueFactory; import org.openrdf.query.BindingSet; import org.openrdf.query.MalformedQueryException; import org.openrdf.query.QueryEvaluationException; import org.openrdf.query.QueryLanguage; import org.openrdf.query.QueryResultHandlerException; import org.openrdf.query.TupleQuery; import org.openrdf.query.TupleQueryResult; import org.openrdf.query.TupleQueryResultHandlerException; import org.openrdf.query.resultio.QueryResultParseException; import org.openrdf.query.resultio.TupleQueryResultParser; import org.openrdf.query.resultio.sparqlxml.SPARQLResultsXMLParserFactory; import org.openrdf.repository.RepositoryException; import org.openrdf.repository.sail.SailRepository; import org.openrdf.repository.sail.SailRepositoryConnection; import org.openrdf.rio.RDFFormat; import org.openrdf.rio.RDFParseException; import org.openrdf.sail.memory.MemoryStore; @RunWith(Parameterized.class) public class SPARQLInferenceTest { private SailRepository repo; private SailRepositoryConnection conn; private ValueFactory vf; private final String name; private final String comment; private final String data; private final String expected; private final String queryString; private TupleQuery query; private TupleQuery nonInfQuery; private TupleQueryResultParser parser; private static InputStream getResource(String name) { if (name == null) { return null; } String pref = "file://"; if (name.startsWith(pref)) { name = name.substring(pref.length()); } return SPARQLInferenceTest.class.getResourceAsStream(name); } private static String getResourceAsString(String name) throws IOException { InputStream in = getResource(name); if (in == null) { return null; } StringWriter writer = new StringWriter(); IOUtils.copy(in, writer, "UTF-8"); return writer.toString(); } @Parameters(name = "{0} - {1}") public static Iterable<Object[]> data() throws RepositoryException, IOException, RDFParseException, MalformedQueryException, QueryEvaluationException { SailRepository repository = new SailRepository(new MemoryStore()); repository.initialize(); SailRepositoryConnection conn = repository.getConnection(); conn.add(getResource("/inference/kiel/manifest.ttl"), "file:///inference/kiel/", RDFFormat.TURTLE); TupleQuery q = conn.prepareTupleQuery(QueryLanguage.SPARQL, getResourceAsString("/inference/queryeval.sparql")); TupleQueryResult r = q.evaluate(); BindingSet b; String name; InputStream data; String query; InputStream result; String comment; ArrayList<Object[]> tests = new ArrayList<>(); while (r.hasNext()) { b = r.next(); String datastr = b.getValue("data").stringValue(); String resultstr = b.getValue("result").stringValue(); name = b.getValue("name").stringValue(); data = getResource(datastr); query = getResourceAsString(b.getValue("query").stringValue()); result = getResource(resultstr); if (b.hasBinding("comment")) { comment = b.getValue("comment").stringValue(); } else { comment = ""; } if (data != null && query != null && result != null) { Object[] test = { name, comment, datastr, query, resultstr }; tests.add(test); } } return tests; } public SPARQLInferenceTest(String name, String comment, String data, String query, String expected) throws RepositoryException { this.name = name; this.comment = comment; this.data = data; this.queryString = query; this.expected = expected; this.query = null; this.parser = null; } @Before public void before() throws RepositoryException, IOException, RDFParseException, MalformedQueryException, QueryResultParseException, QueryResultHandlerException { repo = new SailRepository(new MemoryStore()); repo.initialize(); conn = repo.getConnection(); vf = conn.getValueFactory(); conn.add(getResource(data), "file://", RDFFormat.TURTLE); SPARQLResultsXMLParserFactory factory = new SPARQLResultsXMLParserFactory(); parser = factory.getParser(); parser.setValueFactory(vf); List<Rule> rules; rules = Rules.fromOntology(getResource(data)); QueryRewriter rewriter = new QueryRewriter(conn, rules); query = (TupleQuery) rewriter.rewrite(QueryLanguage.SPARQL, queryString); nonInfQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, queryString); System.out.println("== QUERY (" + this.name + ") =="); System.out.println(nonInfQuery); System.out.println("== REWRITTEN QUERY (" + this.name + ") =="); System.out.println(query); } @After public void after() throws RepositoryException { conn.close(); repo.shutDown(); } private class QueryResult { private final Multiset<BindingSet> expect; private final Multiset<BindingSet> actual; private final Multiset<BindingSet> noninf; public QueryResult(Multiset<BindingSet> expected, Multiset<BindingSet> actual, Multiset<BindingSet> noninf) { this.expect = expected; this.actual = actual; this.noninf = noninf; } public Multiset<BindingSet> getExpected() { return expect; } public Multiset<BindingSet> getActual() { return actual; } public Multiset<BindingSet> getNonInferred() { return noninf; } public Multiset<BindingSet> getDiff() { return Multisets.difference(expect, actual); } @Override public String toString() { return getActual() + "\n" + getExpected(); } } private QueryResult runQuery() throws IOException, QueryEvaluationException, QueryResultParseException, TupleQueryResultHandlerException, QueryResultHandlerException { TestResultHandler noninf = new TestResultHandler(); TestResultHandler actual = new TestResultHandler(); TestResultHandler expect = new TestResultHandler(); parser.setQueryResultHandler(expect); parser.parseQueryResult(getResource(expected)); nonInfQuery.evaluate(noninf); query.evaluate(actual); Multiset<BindingSet> noninfset = noninf.getSolutions(); Multiset<BindingSet> expectset = expect.getSolutions(); Multiset<BindingSet> actualset = actual.getSolutions(); return new QueryResult(expectset, actualset, noninfset); } @org.junit.Rule public ErrorCollector collector = new ErrorCollector(); @Test public void subset() throws QueryEvaluationException, TupleQueryResultHandlerException, IOException, QueryResultParseException, QueryResultHandlerException { QueryResult q = this.runQuery(); assertTrue(q.getNonInferred() + " should be a subset of " + q.getActual(), Multisets.containsOccurrences(q.getActual(), q.getNonInferred())); } @Test public void missing() throws QueryEvaluationException, TupleQueryResultHandlerException, IOException, QueryResultParseException, QueryResultHandlerException { QueryResult q = this.runQuery(); Multiset<BindingSet> missing = q.getExpected(); missing.removeAll(q.getActual()); for (BindingSet b : missing) { collector.addError(new Throwable("Missing " + b + " in result set")); } } @Test public void additional() throws QueryEvaluationException, TupleQueryResultHandlerException, IOException, QueryResultParseException, QueryResultHandlerException { QueryResult q = this.runQuery(); Multiset<BindingSet> additional = q.getActual(); additional.removeAll(q.getExpected()); for (BindingSet b : additional) { collector.addError(new Throwable(b + " shouldn't be in result set")); } } }