You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@marmotta.apache.org by wi...@apache.org on 2014/06/13 10:57:35 UTC
[015/100] [abbrv] [partial] Reverting the erroneous merge by
Sebastian according to the instructions in INFRA-6876
http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/RepositoryTest.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/RepositoryTest.java b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/RepositoryTest.java
index 67ec618..5627f1b 100644
--- a/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/RepositoryTest.java
+++ b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/RepositoryTest.java
@@ -1,13 +1,12 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,32 +16,41 @@
*/
package org.apache.marmotta.kiwi.test;
+import static org.hamcrest.CoreMatchers.hasItems;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.hasProperty;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.lessThan;
+import static org.junit.Assume.assumeThat;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.sql.SQLException;
+import java.util.ConcurrentModificationException;
+import java.util.List;
+
+import org.apache.commons.lang3.RandomStringUtils;
import org.apache.marmotta.commons.sesame.repository.ResourceUtils;
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import org.apache.commons.lang.RandomStringUtils;
-import org.apache.marmotta.kiwi.persistence.KiWiDialect;
-import org.apache.marmotta.kiwi.persistence.h2.H2Dialect;
-import org.apache.marmotta.kiwi.persistence.mysql.MySQLDialect;
-import org.apache.marmotta.kiwi.persistence.pgsql.PostgreSQLDialect;
+import org.apache.marmotta.kiwi.config.KiWiConfiguration;
import org.apache.marmotta.kiwi.sail.KiWiStore;
-import org.apache.marmotta.kiwi.test.helper.DBConnectionChecker;
+import org.apache.marmotta.kiwi.test.junit.KiWiDatabaseRunner;
import org.hamcrest.CoreMatchers;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
-import org.junit.Rule;
import org.junit.Test;
-import org.junit.rules.TestWatcher;
-import org.junit.runner.Description;
import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
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.query.MalformedQueryException;
+import org.openrdf.query.QueryLanguage;
+import org.openrdf.query.Update;
+import org.openrdf.query.UpdateExecutionException;
import org.openrdf.repository.Repository;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.RepositoryException;
@@ -52,110 +60,35 @@ import org.openrdf.rio.RDFParseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.IOException;
-import java.io.InputStream;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
-
-import static org.hamcrest.CoreMatchers.hasItems;
-import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.hamcrest.Matchers.hasItem;
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assume.assumeThat;
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
/**
- * Test the Sesame repository functionality backed by the KiWi triple store. It will try running over all
- * available databases. Except for in-memory databases like H2 or Derby, database URLs must be passed as
- * system property, or otherwise the test is skipped for this database. Available system properties:
- * <ul>
- * <li>PostgreSQL:
- * <ul>
- * <li>postgresql.url, e.g. jdbc:postgresql://localhost:5433/kiwitest?prepareThreshold=3</li>
- * <li>postgresql.user (default: lmf)</li>
- * <li>postgresql.pass (default: lmf)</li>
- * </ul>
- * </li>
- * <li>MySQL:
- * <ul>
- * <li>mysql.url, e.g. jdbc:mysql://localhost:3306/kiwitest?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull</li>
- * <li>mysql.user (default: lmf)</li>
- * <li>mysql.pass (default: lmf)</li>
- * </ul>
- * </li>
- * <li>H2:
- * <ul>
- * <li>h2.url, e.g. jdbc:h2:mem;MVCC=true;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=10</li>
- * <li>h2.user (default: lmf)</li>
- * <li>h2.pass (default: lmf)</li>
- * </ul>
- * </li>
- * </ul>
- * <p/>
- * Author: Sebastian Schaffert
+ * Test the Sesame repository functionality backed by the KiWi triple store.
+ *
+ * @author Sebastian Schaffert (sschaffert@apache.org)
*/
-@RunWith(Parameterized.class)
+@RunWith(KiWiDatabaseRunner.class)
public class RepositoryTest {
private static Logger log = LoggerFactory.getLogger(RepositoryTest.class);
- /**
- * Return database configurations if the appropriate parameters have been set.
- *
- * @return an array (database name, url, user, password)
- */
- @Parameterized.Parameters(name="Database Test {index}: {0} at {1}")
- public static Iterable<Object[]> databases() {
- String[] databases = {"H2", "PostgreSQL", "MySQL"};
-
- List<Object[]> result = new ArrayList<Object[]>(databases.length);
- for(String database : databases) {
- if(System.getProperty(database.toLowerCase()+".url") != null) {
- result.add(new Object[] {
- database,
- System.getProperty(database.toLowerCase()+".url"),
- System.getProperty(database.toLowerCase()+".user","lmf"),
- System.getProperty(database.toLowerCase()+".pass","lmf")
- });
- }
- }
- return result;
- }
-
-
- private KiWiDialect dialect;
-
- private String jdbcUrl;
-
- private String jdbcUser;
-
- private String jdbcPass;
-
private Repository repository;
- private KiWiStore store;
+ private KiWiStore store;
- public RepositoryTest(String database, String jdbcUrl, String jdbcUser, String jdbcPass) {
- this.jdbcPass = jdbcPass;
- this.jdbcUrl = jdbcUrl;
- this.jdbcUser = jdbcUser;
+ private final KiWiConfiguration kiwiConfiguration;
+
+ public RepositoryTest(KiWiConfiguration kiwiConfiguration) {
+ this.kiwiConfiguration = kiwiConfiguration;
- if("H2".equals(database)) {
- this.dialect = new H2Dialect();
- } else if("MySQL".equals(database)) {
- this.dialect = new MySQLDialect();
- } else if("PostgreSQL".equals(database)) {
- this.dialect = new PostgreSQLDialect();
- }
-
- DBConnectionChecker.checkDatabaseAvailability(jdbcUrl, jdbcUser, jdbcPass, this.dialect);
}
- @Before
+ @Before
public void initDatabase() throws RepositoryException {
- store = new KiWiStore("test",jdbcUrl,jdbcUser,jdbcPass,dialect, "http://localhost/context/default", "http://localhost/context/inferred" );
- repository = new SailRepository(store);
+ store = new KiWiStore(kiwiConfiguration);
+ repository = new SailRepository(store);
repository.initialize();
}
@@ -166,19 +99,6 @@ public class RepositoryTest {
repository.shutDown();
}
- final Logger logger =
- LoggerFactory.getLogger(RepositoryTest.class);
-
- @Rule
- public TestWatcher watchman = new TestWatcher() {
- /**
- * Invoked when a test is about to start
- */
- @Override
- protected void starting(Description description) {
- logger.info("{} being run...", description.getMethodName());
- }
- };
/**
* Test importing data; the test will load a small sample RDF file and check whether the expected resources are
@@ -225,7 +145,8 @@ public class RepositoryTest {
);
// test if the result has the expected size
- Assert.assertEquals(4, resources.size());
+ //FIXME: this test is no longer valid, because resource existance is not bound to use as subject
+ //Assert.assertEquals(4, resources.size());
// test if the result contains all resources that have been used as subject
Assert.assertThat(resources, hasItems(
@@ -329,7 +250,9 @@ public class RepositoryTest {
);
// test if the result has the expected size
- Assert.assertEquals(4, resources.size());
+ // FIXME: MARMOTTA-39 (no xsd:string, so one resource is "missing")
+ // Assert.assertEquals(31, resources.size());
+ Assert.assertEquals(30, resources.size());
// test if the result contains all resources that have been used as subject
Assert.assertThat(resources, hasItems(
@@ -355,7 +278,7 @@ public class RepositoryTest {
// the resource hans_meier should not be contained in the list of resources
List<String> resources2 = ImmutableList.copyOf(
Iterables.transform(
- ResourceUtils.listResources(connection),
+ ResourceUtils.listSubjects(connection),
new Function<Resource, String>() {
@Override
public String apply(Resource input) {
@@ -366,7 +289,7 @@ public class RepositoryTest {
);
// test if the result has the expected size
- Assert.assertEquals(3, resources2.size());
+ //Assert.assertEquals(3, resources2.size());
// test if the result does not contain the removed resource
Assert.assertThat(resources2, not(hasItem(
@@ -545,7 +468,329 @@ public class RepositoryTest {
connection4.close();
}
+ // test repeated adding/removing inside the same transaction
+ Literal object5 = repository.getValueFactory().createLiteral(RandomStringUtils.randomAlphanumeric(8));
+ RepositoryConnection connection5 = repository.getConnection();
+ try {
+ Assert.assertFalse(connection5.hasStatement(subject, predicate, object5, true));
+
+ connection5.add(subject,predicate,object5);
+ Assert.assertTrue(connection5.hasStatement(subject,predicate,object5,true));
+
+ connection5.remove(subject,predicate,object5);
+ Assert.assertFalse(connection5.hasStatement(subject,predicate,object5,true));
+
+ connection5.add(subject,predicate,object5);
+ Assert.assertTrue(connection5.hasStatement(subject,predicate,object5,true));
+ connection5.commit();
+ } finally {
+ connection5.close();
+ }
+
+ RepositoryConnection connection6 = repository.getConnection();
+ try {
+ Assert.assertTrue(connection6.hasStatement(subject, predicate, object5, true));
+
+ connection6.commit();
+ } finally {
+ connection6.close();
+ }
+
+ }
+
+ @Test
+ public void testRepeatedAddRemoveCrossTransaction() throws RepositoryException {
+ String value = RandomStringUtils.randomAlphanumeric(8);
+
+ URI subject = repository.getValueFactory().createURI("http://localhost/resource/" + RandomStringUtils.randomAlphanumeric(8));
+ URI predicate = repository.getValueFactory().createURI("http://localhost/resource/" + RandomStringUtils.randomAlphanumeric(8));
+ Literal object1 = repository.getValueFactory().createLiteral(value);
+
+ RepositoryConnection connection1 = repository.getConnection();
+ try {
+ connection1.add(subject,predicate,object1);
+ connection1.commit();
+
+ Assert.assertTrue(connection1.hasStatement(subject,predicate,object1,true));
+
+ connection1.commit();
+ } finally {
+ connection1.close();
+ }
+
+ RepositoryConnection connection2 = repository.getConnection();
+ try {
+ connection2.remove(subject, predicate, object1);
+ Assert.assertFalse(connection2.hasStatement(subject, predicate, object1, true));
+
+ connection2.add(subject,predicate,object1);
+ Assert.assertTrue(connection2.hasStatement(subject, predicate, object1, true));
+
+ connection2.commit();
+ } finally {
+ connection2.close();
+ }
+
+ RepositoryConnection connection3 = repository.getConnection();
+ try {
+ Assert.assertTrue(connection3.hasStatement(subject, predicate, object1, true));
+ connection3.commit();
+ } finally {
+ connection3.close();
+ }
+ }
+
+ @Test
+ public void testRepeatedAddRemoveSPARQL() throws RepositoryException, MalformedQueryException, UpdateExecutionException {
+ String value = RandomStringUtils.randomAlphanumeric(8);
+
+ URI subject = repository.getValueFactory().createURI("http://localhost/resource/" + RandomStringUtils.randomAlphanumeric(8));
+ URI predicate = repository.getValueFactory().createURI("http://localhost/resource/" + RandomStringUtils.randomAlphanumeric(8));
+ Literal object1 = repository.getValueFactory().createLiteral(value);
+
+ RepositoryConnection connection1 = repository.getConnection();
+ try {
+ connection1.add(subject,predicate,object1);
+ connection1.commit();
+
+ Assert.assertTrue(connection1.hasStatement(subject,predicate,object1,true));
+
+ connection1.commit();
+ } finally {
+ connection1.close();
+ }
+
+ RepositoryConnection connection2 = repository.getConnection();
+ try {
+ String query = String.format("DELETE { <%s> <%s> ?v } INSERT { <%s> <%s> ?v . } WHERE { <%s> <%s> ?v }", subject.stringValue(), predicate.stringValue(), subject.stringValue(), predicate.stringValue(), subject.stringValue(), predicate.stringValue());
+
+ Update u = connection2.prepareUpdate(QueryLanguage.SPARQL, query);
+ u.execute();
+ connection2.commit();
+ } finally {
+ connection2.close();
+ }
+
+ RepositoryConnection connection3 = repository.getConnection();
+ try {
+ Assert.assertTrue(connection3.hasStatement(subject, predicate, object1, true));
+ connection3.commit();
+ } finally {
+ connection3.close();
+ }
}
+
+ /**
+ * Test the rollback functionality of the triple store by adding a triple, rolling back, adding the triple again.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testRollback() throws Exception {
+ String value = RandomStringUtils.randomAlphanumeric(8);
+
+ URI subject = repository.getValueFactory().createURI("http://localhost/resource/" + RandomStringUtils.randomAlphanumeric(8));
+ URI predicate = repository.getValueFactory().createURI("http://localhost/resource/" + RandomStringUtils.randomAlphanumeric(8));
+ Literal object = repository.getValueFactory().createLiteral(value);
+
+ RepositoryConnection connection1 = repository.getConnection();
+ try {
+ connection1.begin();
+ connection1.add(subject,predicate,object);
+ connection1.rollback();
+
+ } finally {
+ connection1.close();
+ }
+
+ RepositoryConnection connection2 = repository.getConnection();
+ try {
+ connection2.begin();
+ Assert.assertFalse(connection2.hasStatement(subject,predicate,object,true));
+
+ connection2.add(subject,predicate,object);
+ connection2.commit();
+
+ Assert.assertTrue(connection2.hasStatement(subject,predicate,object,true));
+
+ connection2.commit();
+ } finally {
+ connection2.close();
+ }
+
+ }
+
+ /**
+ * This test is for a strange bug that happens when running SPARQL updates that delete and reinsert a triple in
+ * the same transaction. See https://issues.apache.org/jira/browse/MARMOTTA-283
+ */
+ @Test
+ public void testMARMOTTA283() throws RepositoryException, RDFParseException, IOException, MalformedQueryException, UpdateExecutionException {
+
+ InputStream rdfXML = this.getClass().getResourceAsStream("demo-data.foaf");
+ assumeThat("Could not load test-data: demo-data.foaf", rdfXML, notNullValue(InputStream.class));
+
+ RepositoryConnection connectionRDF = repository.getConnection();
+ try {
+ connectionRDF.add(rdfXML, "http://localhost/foaf/", RDFFormat.RDFXML);
+ connectionRDF.commit();
+ } finally {
+ connectionRDF.close();
+ }
+
+
+ String update = "DELETE { ?s ?p ?o } INSERT { <http://localhost:8080/LMF/resource/hans_meier> <http://xmlns.com/foaf/0.1/name> \"Hans Meier\" . <http://localhost:8080/LMF/resource/hans_meier> <http://xmlns.com/foaf/0.1/based_near> <http://dbpedia.org/resource/Traunstein> . <http://localhost:8080/LMF/resource/hans_meier> <http://xmlns.com/foaf/0.1/interest> <http://rdf.freebase.com/ns/en.linux> } WHERE { ?s ?p ?o . FILTER ( ?s = <http://localhost:8080/LMF/resource/hans_meier> ) }";
+
+ RepositoryConnection connectionUpdate = repository.getConnection();
+ try {
+ Update u = connectionUpdate.prepareUpdate(QueryLanguage.SPARQL, update);
+ u.execute();
+ connectionUpdate.commit();
+ } finally {
+ connectionUpdate.close();
+ }
+
+ // now there should be two triples
+ RepositoryConnection connectionVerify = repository.getConnection();
+ try {
+ URI hans_meier = repository.getValueFactory().createURI("http://localhost:8080/LMF/resource/hans_meier");
+ URI foaf_name = repository.getValueFactory().createURI("http://xmlns.com/foaf/0.1/name");
+ URI foaf_based_near = repository.getValueFactory().createURI("http://xmlns.com/foaf/0.1/based_near");
+ URI foaf_interest = repository.getValueFactory().createURI("http://xmlns.com/foaf/0.1/interest");
+ URI freebase_linux = repository.getValueFactory().createURI("http://rdf.freebase.com/ns/en.linux");
+ URI traunstein = repository.getValueFactory().createURI("http://dbpedia.org/resource/Traunstein");
+
+ Assert.assertTrue(connectionVerify.hasStatement(hans_meier,foaf_name,null, true));
+ Assert.assertTrue(connectionVerify.hasStatement(hans_meier,foaf_based_near,traunstein, true));
+ Assert.assertTrue(connectionVerify.hasStatement(hans_meier,foaf_interest,freebase_linux, true));
+
+ connectionVerify.commit();
+ } finally {
+ connectionVerify.close();
+ }
+ }
+
+ /**
+ * This test is for a strange bug that happens when running SPARQL updates that delete and reinsert a triple in
+ * the same transaction. It is similar to #testMARMOTTA283, but simulates the issue in more detail.
+ * See https://issues.apache.org/jira/browse/MARMOTTA-283
+ */
+ @Test
+ public void testMARMOTTA283_2() throws RepositoryException, RDFParseException, IOException, MalformedQueryException, UpdateExecutionException {
+
+ //insert quadruples
+ String insert =
+ "WITH <http://resource.org/video>" +
+ "INSERT {" +
+ " <http://resource.org/video> <http://ontology.org#hasFragment> <http://resource.org/fragment1>." +
+ " <http://resource.org/annotation1> <http://ontology.org#hasTarget> <http://resource.org/fragment1>." +
+ " <http://resource.org/annotation1> <http://ontology.org#hasBody> <http://resource.org/subject1>." +
+ " <http://resource.org/fragment1> <http://ontology.org#shows> <http://resource.org/subject1>." +
+ "} WHERE {}";
+
+ RepositoryConnection connectionInsert = repository.getConnection();
+ try {
+ Update u = connectionInsert.prepareUpdate(QueryLanguage.SPARQL, insert);
+ u.execute();
+ connectionInsert.commit();
+ } finally {
+ connectionInsert.close();
+ }
+
+ //update quadruples
+ String update =
+ "WITH <http://resource.org/video>" +
+ "DELETE { " +
+ " ?annotation ?p ?v." +
+ " ?fragment ?r ?s." +
+ " <http://resource.org/video> <http://ontology.org#hasFragment> ?fragment." +
+ "} INSERT {" +
+ " <http://resource.org/video> <http://ontology.org#hasFragment> <http://resource.org/fragment1>." +
+ " <http://resource.org/annotation1> <http://ontology.org#hasTarget> <http://resource.org/fragment1>." +
+ " <http://resource.org/annotation1> <http://ontology.org#hasBody> <http://resource.org/subject1>." +
+ " <http://resource.org/fragment1> <http://ontology.org#shows> <http://resource.org/subject1>." +
+ "} WHERE {" +
+ " ?annotation <http://ontology.org#hasTarget> ?fragment." +
+ " ?annotation ?p ?v." +
+ " OPTIONAL {" +
+ " ?fragment ?r ?s" +
+ " }" +
+ " FILTER (?fragment = <http://resource.org/fragment1>)" +
+ "} ";
+
+ RepositoryConnection connectionUpdate = repository.getConnection();
+ try {
+ Update u = connectionUpdate.prepareUpdate(QueryLanguage.SPARQL, update);
+ u.execute();
+ connectionUpdate.commit();
+ } finally {
+ connectionUpdate.close();
+ }
+
+ //check quadruples
+ RepositoryConnection connectionVerify = repository.getConnection();
+ try {
+ URI video = repository.getValueFactory().createURI("http://resource.org/video");
+ URI hasFragment = repository.getValueFactory().createURI("http://ontology.org#hasFragment");
+ URI fragment = repository.getValueFactory().createURI("http://resource.org/fragment1");
+ URI annotation = repository.getValueFactory().createURI("http://resource.org/annotation1");
+ URI hasTarget = repository.getValueFactory().createURI("http://ontology.org#hasTarget");
+ URI hasBody = repository.getValueFactory().createURI("http://ontology.org#hasBody");
+ URI subject = repository.getValueFactory().createURI("http://resource.org/subject1");
+ URI shows = repository.getValueFactory().createURI("http://ontology.org#shows");
+
+ Assert.assertTrue(connectionVerify.hasStatement(video,hasFragment,fragment,true,video));
+ Assert.assertTrue(connectionVerify.hasStatement(annotation,hasTarget,fragment,true,video));
+ Assert.assertTrue(connectionVerify.hasStatement(annotation,hasBody,subject,true,video));
+ Assert.assertTrue(connectionVerify.hasStatement(fragment,shows,subject,true,video));
+
+ connectionVerify.commit();
+ } finally {
+ connectionVerify.close();
+ }
+ }
+
+ /**
+ * Test the concurrent connection problem reported in MARMOTTA-236 for facading:
+ * - get two parallel connections
+ * - add triple in connection 1; should be available in connection 1 and not in connection 2
+ * - add same triple in connection 2; should be available in both, connection 1 and connection 2 or
+ * fail-fast by throwing a ConcurrentModificationException
+ * @throws Exception
+ */
+ @Test
+ public void testMARMOTTA236() throws Exception {
+ RepositoryConnection con1 = repository.getConnection();
+ RepositoryConnection con2 = repository.getConnection();
+
+ try {
+ URI r1 = repository.getValueFactory().createURI("http://localhost/"+ RandomStringUtils.randomAlphanumeric(8));
+ URI r2 = repository.getValueFactory().createURI("http://localhost/"+ RandomStringUtils.randomAlphanumeric(8));
+ URI r3 = repository.getValueFactory().createURI("http://localhost/"+ RandomStringUtils.randomAlphanumeric(8));
+
+ con1.begin();
+ con1.add(r1,r2,r3);
+
+ Assert.assertTrue(con1.hasStatement(r1,r2,r3,true));
+
+ con2.begin();
+ Assert.assertFalse(con2.hasStatement(r1,r2,r3,true));
+
+ con2.add(r1,r2,r3);
+
+ Assert.assertTrue(con2.hasStatement(r1,r2,r3,true));
+
+ con2.rollback();
+ con1.commit();
+ } catch (ConcurrentModificationException ex) {
+
+ } finally {
+ con1.close();
+ con2.close();
+ }
+
+
+ }
}
http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/helper/DBConnectionChecker.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/helper/DBConnectionChecker.java b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/helper/DBConnectionChecker.java
index 6b429f4..bce19b6 100644
--- a/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/helper/DBConnectionChecker.java
+++ b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/helper/DBConnectionChecker.java
@@ -1,13 +1,12 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,33 +16,84 @@
*/
package org.apache.marmotta.kiwi.test.helper;
-import org.apache.marmotta.kiwi.persistence.KiWiDialect;
-import org.junit.Assume;
-
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
+import org.apache.marmotta.kiwi.config.KiWiConfiguration;
+import org.apache.marmotta.kiwi.persistence.KiWiDialect;
+import org.junit.Assume;
+import org.junit.internal.AssumptionViolatedException;
+
public class DBConnectionChecker {
- private DBConnectionChecker() {
- // static only
- }
-
- public static void checkDatabaseAvailability(String jdbcUrl, String jdbcUser,
- String jdbcPass, KiWiDialect dialect) {
- try {
- Class.forName(dialect.getDriverClass());
- Connection conn = DriverManager.getConnection(jdbcUrl, jdbcUser, jdbcPass);
+ private DBConnectionChecker() {
+ // static only
+ }
+
+ /**
+ * Check availability of the Database.
+ * @param jdbcUrl - the jdbcURL
+ * @param jdbcUser - the user
+ * @param jdbcPass - the password
+ * @param dialect - the {@link KiWiDialect}
+ * @throws AssumptionViolatedException if the database is not available.
+ */
+ public static void checkDatabaseAvailability(String jdbcUrl, String jdbcUser,
+ String jdbcPass, KiWiDialect dialect) throws AssumptionViolatedException {
+ try {
+ Class.forName(dialect.getDriverClass());
+ Connection conn = DriverManager.getConnection(jdbcUrl, jdbcUser, jdbcPass);
conn.setAutoCommit(false);
- Assume.assumeTrue("Database not available", conn.isValid(1000));
- conn.commit();
- conn.close();
- } catch (SQLException e) {
- Assume.assumeNoException("Database not available", e);
- } catch (ClassNotFoundException e) {
- Assume.assumeNoException("Missing DB driver", e);
- }
- }
+ Assume.assumeTrue("Database not available", conn.isValid(1000));
+ conn.commit();
+ conn.close();
+ } catch (SQLException e) {
+ Assume.assumeNoException("Database not available", e);
+ } catch (ClassNotFoundException e) {
+ Assume.assumeNoException("Missing DB driver", e);
+ }
+ }
+
+ /**
+ * Check availability of the Database.
+ * @param config the {@link KiWiConfiguration} to test
+ * @throws AssumptionViolatedException if the database is not available.
+ */
+ public static void checkDatabaseAvailability(KiWiConfiguration config) throws AssumptionViolatedException {
+ checkDatabaseAvailability(config.getJdbcUrl(), config.getDbUser(), config.getDbPassword(), config.getDialect());
+ }
+
+ /**
+ * Check the availability of the Database.
+ * @param jdbcUrl - the jdbcURL
+ * @param jdbcUser - the user
+ * @param jdbcPass - the password
+ * @param dialect - the {@link KiWiDialect}
+ * @return {@code true} if the database is available, {@code false} if not
+ */
+ public static boolean isDatabaseAvailable(String jdbcUrl, String jdbcUser,
+ String jdbcPass, KiWiDialect dialect) {
+ try {
+ checkDatabaseAvailability(jdbcUrl, jdbcUser, jdbcPass, dialect);
+ return true;
+ } catch (AssumptionViolatedException ave) {
+ return false;
+ }
+ }
+
+ /**
+ * Check availability of the Database.
+ * @param config the {@link KiWiConfiguration} to test
+ * @return {@code true} if the database is available, {@code false} if not
+ */
+ public static boolean isDatabaseAvailable(KiWiConfiguration config) {
+ try {
+ checkDatabaseAvailability(config);
+ return true;
+ } catch (AssumptionViolatedException ave) {
+ return false;
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/junit/DatabaseRunnerTest1.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/junit/DatabaseRunnerTest1.java b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/junit/DatabaseRunnerTest1.java
new file mode 100644
index 0000000..cee043e
--- /dev/null
+++ b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/junit/DatabaseRunnerTest1.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.kiwi.test.junit;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.not;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+
+import org.apache.marmotta.kiwi.config.KiWiConfiguration;
+import org.apache.marmotta.kiwi.persistence.h2.H2Dialect;
+import org.apache.marmotta.kiwi.persistence.mysql.MySQLDialect;
+import org.apache.marmotta.kiwi.persistence.pgsql.PostgreSQLDialect;
+import org.apache.marmotta.kiwi.test.junit.KiWiDatabaseRunner.ForDialects;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(KiWiDatabaseRunner.class)
+public class DatabaseRunnerTest1 {
+
+ private final KiWiConfiguration dbConfig;
+
+ public DatabaseRunnerTest1(KiWiConfiguration dbConfig) {
+ this.dbConfig = dbConfig;
+ }
+
+ @Test
+ public void testDatabase() {
+ assertNotNull(dbConfig);
+ }
+
+ @Test
+ @ForDialects(H2Dialect.class)
+ public void testOnlyH2() {
+ assertThat(dbConfig.getDialect(), instanceOf(H2Dialect.class));
+ }
+
+ @Test
+ @ForDialects(PostgreSQLDialect.class)
+ public void testOnlyPostgreSQL() {
+ assertThat(dbConfig.getDialect(), instanceOf(PostgreSQLDialect.class));
+ }
+
+ @Test
+ @ForDialects(MySQLDialect.class)
+ public void testOnlyMySQL() {
+ assertThat(dbConfig.getDialect(), instanceOf(MySQLDialect.class));
+ }
+
+ @Test
+ @ForDialects({PostgreSQLDialect.class, MySQLDialect.class})
+ public void testNotH2() {
+ assertThat(dbConfig.getDialect(), not(instanceOf(H2Dialect.class)));
+ }
+
+ @Test
+ @ForDialects({H2Dialect.class, MySQLDialect.class})
+ public void testNotPostgreSQL() {
+ assertThat(dbConfig.getDialect(), not(instanceOf(PostgreSQLDialect.class)));
+ }
+
+ @Test
+ @ForDialects({PostgreSQLDialect.class, H2Dialect.class})
+ public void testNotMySQL() {
+ assertThat(dbConfig.getDialect(), not(instanceOf(MySQLDialect.class)));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/junit/DatabaseRunnerTest2.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/junit/DatabaseRunnerTest2.java b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/junit/DatabaseRunnerTest2.java
new file mode 100644
index 0000000..d903698
--- /dev/null
+++ b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/junit/DatabaseRunnerTest2.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.kiwi.test.junit;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.not;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+
+import org.apache.marmotta.kiwi.config.KiWiConfiguration;
+import org.apache.marmotta.kiwi.persistence.h2.H2Dialect;
+import org.apache.marmotta.kiwi.persistence.mysql.MySQLDialect;
+import org.apache.marmotta.kiwi.persistence.pgsql.PostgreSQLDialect;
+import org.apache.marmotta.kiwi.test.junit.KiWiDatabaseRunner.ForDialects;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(KiWiDatabaseRunner.class)
+public class DatabaseRunnerTest2 {
+
+ @KiWiDatabaseRunner.KiWiConfig
+ public KiWiConfiguration dbConfig;
+
+ @Test
+ public void testDatabase() {
+ assertNotNull(dbConfig);
+ }
+
+ @Test
+ @ForDialects(H2Dialect.class)
+ public void testOnlyH2() {
+ assertThat(dbConfig.getDialect(), instanceOf(H2Dialect.class));
+ }
+
+ @Test
+ @ForDialects(PostgreSQLDialect.class)
+ public void testOnlyPostgreSQL() {
+ assertThat(dbConfig.getDialect(), instanceOf(PostgreSQLDialect.class));
+ }
+
+ @Test
+ @ForDialects(MySQLDialect.class)
+ public void testOnlyMySQL() {
+ assertThat(dbConfig.getDialect(), instanceOf(MySQLDialect.class));
+ }
+
+ @Test
+ @ForDialects({PostgreSQLDialect.class, MySQLDialect.class})
+ public void testNotH2() {
+ assertThat(dbConfig.getDialect(), not(instanceOf(H2Dialect.class)));
+ }
+
+ @Test
+ @ForDialects({H2Dialect.class, MySQLDialect.class})
+ public void testNotPostgreSQL() {
+ assertThat(dbConfig.getDialect(), not(instanceOf(PostgreSQLDialect.class)));
+ }
+
+ @Test
+ @ForDialects({PostgreSQLDialect.class, H2Dialect.class})
+ public void testNotMySQL() {
+ assertThat(dbConfig.getDialect(), not(instanceOf(MySQLDialect.class)));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/junit/KiWiDatabaseRunner.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/junit/KiWiDatabaseRunner.java b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/junit/KiWiDatabaseRunner.java
new file mode 100644
index 0000000..170fdba
--- /dev/null
+++ b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/junit/KiWiDatabaseRunner.java
@@ -0,0 +1,340 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.kiwi.test.junit;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.marmotta.kiwi.config.KiWiConfiguration;
+import org.apache.marmotta.kiwi.persistence.KiWiDialect;
+import org.apache.marmotta.kiwi.persistence.h2.H2Dialect;
+import org.apache.marmotta.kiwi.persistence.mysql.MySQLDialect;
+import org.apache.marmotta.kiwi.persistence.pgsql.PostgreSQLDialect;
+import org.apache.marmotta.kiwi.test.helper.DBConnectionChecker;
+import org.junit.internal.AssumptionViolatedException;
+import org.junit.rules.MethodRule;
+import org.junit.rules.TestWatcher;
+import org.junit.runner.Runner;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Suite;
+import org.junit.runners.model.FrameworkField;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.Statement;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Specialized {@link Parameterized} runner for UnitTests that injects the database config for KiWi.
+ * <p>
+ * Except for in-memory databases like H2 or Derby, database URLs must be passed as
+ * system property, or otherwise the test is skipped for this database. Available system properties:
+ * <ul>
+ * <li>PostgreSQL:
+ * <ul>
+ * <li>postgresql.url, e.g. jdbc:postgresql://localhost:5433/kiwitest?prepareThreshold=3</li>
+ * <li>postgresql.user (default: kiwi)</li>
+ * <li>postgresql.pass (default: kiwi)</li>
+ * </ul>
+ * </li>
+ * <li>MySQL:
+ * <ul>
+ * <li>mysql.url, e.g. jdbc:mysql://localhost:3306/kiwitest?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull</li>
+ * <li>mysql.user (default: kiwi)</li>
+ * <li>mysql.pass (default: kiwi)</li>
+ * </ul>
+ * </li>
+ * <li>H2:
+ * <ul>
+ * <li>h2.url, e.g. jdbc:h2:mem:kiwitest;MVCC=true;DB_CLOSE_ON_EXIT=TRUE</li>
+ * <li>h2.user (default: kiwi)</li>
+ * <li>h2.pass (default: kiwi)</li>
+ * </ul>
+ * </li>
+ * </ul>
+ * @author Jakob Frank <ja...@apache.org>
+ *
+ */
+public class KiWiDatabaseRunner extends Suite {
+
+ /**
+ * Assign the {@link KiWiConfiguration} to all member fields with {@link KiWiConfig}-Annotation.
+ * If this annotation is used, the class must only have the default constructor.
+ */
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.FIELD)
+ public static @interface KiWiConfig {
+ }
+
+ /**
+ * Only execute with {@link KiWiConfiguration}s for these {@link KiWiDialect}s.
+ */
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target({ElementType.TYPE, ElementType.METHOD})
+ public static @interface ForDialects {
+ Class<? extends KiWiDialect>[] value();
+ }
+
+ private final ArrayList<Runner> runners = new ArrayList<Runner>();
+
+ private final List<Class<? extends KiWiDialect>> forDialects;
+
+ public KiWiDatabaseRunner(Class<?> klass) throws Throwable {
+ super(klass, Collections.<Runner>emptyList());
+
+ ForDialects d = klass.getAnnotation(ForDialects.class);
+ if (d != null) {
+ ArrayList<Class<? extends KiWiDialect>> forDialects = new ArrayList<>();
+ for (Class<? extends KiWiDialect> dialect : d.value()) {
+ forDialects.add(dialect);
+ }
+ this.forDialects = Collections.unmodifiableList(forDialects);
+ } else {
+ forDialects = null;
+ }
+
+ createRunners();
+ }
+
+ private void createRunners() throws InitializationError {
+ List<KiWiConfiguration> configs = new ArrayList<>();
+ createKiWiConfig("H2", new H2Dialect(), configs);
+ createKiWiConfig("PostgreSQL", new PostgreSQLDialect(), configs);
+ createKiWiConfig("MySQL", new MySQLDialect(), configs);
+
+ for (KiWiConfiguration config : configs) {
+ final DatabaseTestClassRunner runner = new DatabaseTestClassRunner(getTestClass().getJavaClass(), config);
+ runners.add(runner);
+ }
+ }
+
+ private void createKiWiConfig(String database, KiWiDialect dialect, List<KiWiConfiguration> configs) {
+ if (forDialects != null && !forDialects.contains(dialect.getClass())) {
+ return;
+ }
+ KiWiConfiguration c = createKiWiConfig(database, dialect);
+ if (c!=null) configs.add(c);
+ }
+
+ public static KiWiConfiguration createKiWiConfig(String database, KiWiDialect dialect) {
+ final KiWiConfiguration config;
+ if(!(dialect instanceof H2Dialect) && System.getProperty(database.toLowerCase()+".url") != null) {
+ config = new KiWiConfiguration(
+ database,
+ System.getProperty(database.toLowerCase()+".url"),
+ System.getProperty(database.toLowerCase()+".user","kiwi"),
+ System.getProperty(database.toLowerCase()+".pass","kiwi"),
+ dialect);
+ } else if (dialect instanceof H2Dialect) {
+ config = new KiWiConfiguration(
+ "default-H2",
+ "jdbc:h2:mem:kiwitest;MVCC=true;DB_CLOSE_ON_EXIT=TRUE;DB_CLOSE_DELAY=-1",
+ "kiwi", "kiwi",
+ dialect);
+ } else {
+ return null;
+ }
+ config.setDefaultContext("http://localhost/context/default");
+ config.setInferredContext("http://localhost/context/inferred");
+ return config;
+ }
+
+ @Override
+ protected List<Runner> getChildren() {
+ return runners;
+ }
+
+ private class DatabaseTestClassRunner extends BlockJUnit4ClassRunner {
+
+ private final KiWiConfiguration config;
+
+ private final Logger logger;
+
+ private final CheckDBRule checkDB;
+ private final ExecutionLogger loggerRule;
+
+ public DatabaseTestClassRunner(Class<?> klass, KiWiConfiguration config)
+ throws InitializationError {
+ super(klass);
+ logger = LoggerFactory.getLogger(klass);
+ this.config = config;
+
+ checkDB = new CheckDBRule(config);
+ loggerRule = new ExecutionLogger();
+ }
+
+ @Override
+ protected void runChild(FrameworkMethod method, RunNotifier notifier) {
+ final ForDialects forD = method.getAnnotation(ForDialects.class);
+ if (forD != null) {
+ if (ArrayUtils.contains(forD.value(), config.getDialect().getClass())) {
+ super.runChild(method, notifier);
+ } else {
+ notifier.fireTestIgnored(describeChild(method));
+ }
+ } else {
+ super.runChild(method, notifier);
+ }
+
+ }
+
+ @Override
+ protected Object createTest() throws Exception {
+ if (fieldAnnotated()) {
+ Object testInstance = getTestClass().getOnlyConstructor().newInstance();
+ List<FrameworkField> configFields = getFieldsAnnotatedByKiWiConfig();
+ for (FrameworkField field : configFields) {
+ try {
+ field.getField().set(testInstance, config);
+ } catch (IllegalArgumentException iae) {
+ throw new Exception(getTestClass().getName() + ": Trying to set " + field.getName() + " that has a wrong type.");
+ }
+ }
+ return testInstance;
+ }
+ return getTestClass().getOnlyConstructor().newInstance(config);
+ }
+
+ @Override
+ protected List<MethodRule> rules(Object target) {
+ LinkedList<MethodRule> rules = new LinkedList<>();
+ rules.add(loggerRule);
+ rules.addAll(super.rules(target));
+ rules.add(checkDB);
+ return rules;
+ }
+
+ @Override
+ protected String getName() {
+ return "KiWi-Triplestore - " + config.getName();
+ }
+
+ @Override
+ protected String testName(FrameworkMethod method) {
+ return method.getName() + "(" + config.getName() + ")";
+ }
+
+ @Override
+ protected void validateConstructor(List<Throwable> errors) {
+ validateOnlyOneConstructor(errors);
+ if (fieldAnnotated()) {
+ validateZeroArgConstructor(errors);
+ }
+ }
+
+ @Override
+ protected void validateFields(List<Throwable> errors) {
+ super.validateFields(errors);
+ if (fieldAnnotated()) {
+ List<FrameworkField> configFields = getFieldsAnnotatedByKiWiConfig();
+ for (FrameworkField field : configFields) {
+ if (!field.getType().isAssignableFrom(KiWiConfiguration.class)) {
+ errors.add(new Exception(String.format("Invalid type %s for field %s, must be %s", field.getType().getName(), field.getName(), KiWiConfiguration.class.getSimpleName())));
+ }
+ }
+ }
+ }
+
+ @Override
+ protected Statement classBlock(RunNotifier notifier) {
+ return childrenInvoker(notifier);
+ }
+
+ @Override
+ protected Annotation[] getRunnerAnnotations() {
+ return new Annotation[0];
+ }
+
+ private class CheckDBRule implements MethodRule {
+
+ private final AssumptionViolatedException assume;
+
+ public CheckDBRule(KiWiConfiguration dbConfig) {
+ AssumptionViolatedException ex = null;
+ try {
+ DBConnectionChecker.checkDatabaseAvailability(dbConfig);
+ } catch (AssumptionViolatedException ave) {
+ ex = ave;
+ }
+ this.assume = ex;
+ }
+
+ @Override
+ public Statement apply(final Statement base, final FrameworkMethod method,
+ Object target) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ if (assume != null) {
+ logger.info("{} skipped because database is not available", testName(method));
+ throw assume;
+ }
+ base.evaluate();
+ }
+ };
+ }
+
+ }
+
+ private class ExecutionLogger extends TestWatcher implements MethodRule {
+
+
+ @Override
+ public Statement apply(final Statement base, final FrameworkMethod method,
+ Object target) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ logger.info("{} starting...", testName(method));
+ try {
+ base.evaluate();
+ logger.debug("{} SUCCESS", testName(method));
+ } catch (AssumptionViolatedException e) {
+ logger.info("{} Ignored: {}", testName(method), e.getMessage());
+ throw e;
+ } catch (Throwable t) {
+ logger.warn("{} FAILED: {}", testName(method), t.getMessage());
+ throw t;
+ }
+ }
+ };
+ }
+
+ }
+
+ }
+
+ private boolean fieldAnnotated() {
+ return !getFieldsAnnotatedByKiWiConfig().isEmpty();
+ }
+
+ private List<FrameworkField> getFieldsAnnotatedByKiWiConfig() {
+ return getTestClass().getAnnotatedFields(KiWiConfig.class);
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/sesame/KiWiLocaleTest.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/sesame/KiWiLocaleTest.java b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/sesame/KiWiLocaleTest.java
new file mode 100644
index 0000000..7815127
--- /dev/null
+++ b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/sesame/KiWiLocaleTest.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.kiwi.test.sesame;
+
+import org.apache.marmotta.kiwi.config.KiWiConfiguration;
+import org.apache.marmotta.kiwi.sail.KiWiStore;
+import org.apache.marmotta.kiwi.sail.KiWiValueFactory;
+import org.apache.marmotta.kiwi.test.junit.KiWiDatabaseRunner;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.openrdf.model.Literal;
+import org.openrdf.sail.SailConnection;
+import org.openrdf.sail.SailException;
+
+import java.sql.SQLException;
+
+/**
+ * Tests for testing locales against the KiWi Triple store
+ * (and its implementation of the ValueFactory)
+ *
+ * @author Sergio Fernández <wi...@apache.org>
+ */
+@RunWith(KiWiDatabaseRunner.class)
+public class KiWiLocaleTest {
+
+ private final KiWiConfiguration kiwiConfig;
+ private KiWiStore store;
+ private KiWiValueFactory vf;
+
+ public KiWiLocaleTest(KiWiConfiguration kiwiConfig) {
+ this.kiwiConfig = kiwiConfig;
+ }
+
+ @Before
+ public void initialize() throws SailException {
+ store = new KiWiStore(kiwiConfig);
+ store.initialize();
+ vf = new KiWiValueFactory(store, "http://example.org");
+ }
+
+ @After
+ public void shutdown() throws SailException, SQLException {
+ store.getPersistence().dropDatabase();
+ store.shutDown();
+ store = null;
+ vf = null;
+ }
+
+ /**
+ * Tests creating BCP47 literals (see MARMOTTA-115 for further details)
+ */
+ @Test
+ public void createBCP47LiteralsTests() {
+ Literal enLiteral = vf.createLiteral("Hungary", "en");
+ Assert.assertEquals("Hungary", enLiteral.getLabel());
+ Assert.assertEquals("en", enLiteral.getLanguage());
+ Literal warLiteral = vf.createLiteral("Hungary", "war");
+ Assert.assertEquals("Hungary", warLiteral.getLabel());
+ Assert.assertEquals("war", warLiteral.getLanguage());
+ }
+
+ /**
+ * Tests creating invalid BCP47 literals (see MARMOTTA-115 for further details)
+ */
+ @Test
+ public void createBCP47LiteralsInvalidTests() {
+ Literal invalidLangLiteral = vf.createLiteral("Hungary", "invalid-bcp47-languagetag");
+ Assert.assertEquals("Hungary", invalidLangLiteral.getLabel());
+ Assert.assertNull(invalidLangLiteral.getLanguage());
+ }
+
+// /**
+// * Tests adding BCP47 literals (see MARMOTTA-115 for further details)
+// */
+// @Test
+// public void addBCP47LiteralsTests() throws SailException {
+// SailConnection conn = store.getConnection();
+// try {
+// conn.begin();
+// conn.commit();
+// } finally {
+// conn.close();
+// }
+//
+// }
+//
+// /**
+// * Tests importing BCP47 literals (see MARMOTTA-115 for further details)
+// */
+// @Test
+// public void importBCP47LiteralsTests() throws SailException {
+// SailConnection connection = store.getConnection();
+//
+// }
+
+}
http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/sesame/KiWiSailConcurrencyTest.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/sesame/KiWiSailConcurrencyTest.java b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/sesame/KiWiSailConcurrencyTest.java
new file mode 100644
index 0000000..c5661c7
--- /dev/null
+++ b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/sesame/KiWiSailConcurrencyTest.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.kiwi.test.sesame;
+
+import org.apache.marmotta.kiwi.config.KiWiConfiguration;
+import org.apache.marmotta.kiwi.sail.KiWiStore;
+import org.apache.marmotta.kiwi.test.junit.KiWiDatabaseRunner;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.openrdf.sail.Sail;
+import org.openrdf.sail.SailConcurrencyTest;
+import org.openrdf.sail.SailException;
+import org.openrdf.sail.helpers.SailWrapper;
+
+import java.sql.SQLException;
+
+import static org.junit.Assert.fail;
+
+/**
+ * Run the Sesame {@link SailConcurrencyTest} suite.
+ * @author Jakob Frank <ja...@apache.org>
+ */
+@RunWith(KiWiDatabaseRunner.class)
+public class KiWiSailConcurrencyTest extends SailConcurrencyTest {
+
+ private final KiWiConfiguration kiwiConfig;
+
+ public KiWiSailConcurrencyTest(KiWiConfiguration kiwiConfig) {
+ super(String.format("%s (%S)", KiWiSailConcurrencyTest.class.getSimpleName(), kiwiConfig.getName()));
+ this.kiwiConfig = kiwiConfig;
+ }
+
+ @Override
+ protected Sail createSail() throws SailException {
+ Sail store = new SailWrapper(new KiWiStore(kiwiConfig)) {
+ @Override
+ public void shutDown() throws SailException {
+ try {
+ ((KiWiStore)getBaseSail()).getPersistence().dropDatabase();
+ } catch (SQLException e) {
+ fail("SQL exception while deleting database");
+ }
+
+ super.shutDown();
+ }
+ };
+ return store;
+ }
+
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ @Override
+ @Test
+ public void testGetContextIDs() throws Exception {
+ super.testGetContextIDs();
+ }
+}
http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/sesame/KiWiSailInterruptTest.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/sesame/KiWiSailInterruptTest.java b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/sesame/KiWiSailInterruptTest.java
new file mode 100644
index 0000000..710f128
--- /dev/null
+++ b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/sesame/KiWiSailInterruptTest.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.kiwi.test.sesame;
+
+import org.apache.marmotta.kiwi.config.KiWiConfiguration;
+import org.apache.marmotta.kiwi.sail.KiWiStore;
+import org.apache.marmotta.kiwi.test.junit.KiWiDatabaseRunner;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.openrdf.sail.Sail;
+import org.openrdf.sail.SailException;
+import org.openrdf.sail.SailInterruptTest;
+
+/**
+ * Run the Sesame {@link SailInterruptTest} suite.
+ * @author Jakob Frank <ja...@apache.org>
+ *
+ */
+@RunWith(KiWiDatabaseRunner.class)
+public class KiWiSailInterruptTest extends SailInterruptTest {
+
+ private final KiWiConfiguration kiwiConfig;
+
+ public KiWiSailInterruptTest(KiWiConfiguration kiwiConfig) {
+ super(String.format("%s (%S)", KiWiSailInterruptTest.class.getSimpleName(), kiwiConfig.getName()));
+ this.kiwiConfig = kiwiConfig;
+
+ }
+
+
+
+ @Override
+ protected Sail createSail() throws SailException {
+ KiWiStore store = new KiWiStore(kiwiConfig);
+ return store;
+ }
+
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ @Override
+ @Test
+ public void testQueryInterrupt() throws Exception {
+ super.testQueryInterrupt();
+ }
+}
http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/sesame/KiWiStoreTest.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/sesame/KiWiStoreTest.java b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/sesame/KiWiStoreTest.java
new file mode 100644
index 0000000..081dae4
--- /dev/null
+++ b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/sesame/KiWiStoreTest.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.kiwi.test.sesame;
+
+import org.apache.marmotta.kiwi.config.KiWiConfiguration;
+import org.apache.marmotta.kiwi.sail.KiWiStore;
+import org.apache.marmotta.kiwi.test.junit.KiWiDatabaseRunner;
+import org.junit.runner.RunWith;
+import org.openrdf.sail.RDFStoreTest;
+import org.openrdf.sail.Sail;
+import org.openrdf.sail.SailException;
+import org.openrdf.sail.helpers.SailWrapper;
+
+import java.sql.SQLException;
+
+import static org.junit.Assert.fail;
+
+/**
+ * Run the Sesame {@link RDFStoreTest} suite.
+ * @author Jakob Frank <ja...@apache.org>
+ */
+@RunWith(KiWiDatabaseRunner.class)
+public class KiWiStoreTest extends RDFStoreTest {
+
+ private final KiWiConfiguration kiwiConfig;
+
+ public KiWiStoreTest(KiWiConfiguration kiwiConfig) {
+ this.kiwiConfig = kiwiConfig;
+ }
+
+ @Override
+ protected Sail createSail() throws SailException {
+ Sail store = new SailWrapper(new KiWiStore(kiwiConfig)) {
+ @Override
+ public void shutDown() throws SailException {
+ try {
+ ((KiWiStore)getBaseSail()).getPersistence().dropDatabase();
+ } catch (SQLException e) {
+ fail("SQL exception while deleting database");
+ }
+
+ super.shutDown();
+ }
+ };
+ store.initialize();
+ return store;
+ }
+
+
+
+
+}
http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/sesame/repository/KiWiRepositoryConnectionTest.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/sesame/repository/KiWiRepositoryConnectionTest.java b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/sesame/repository/KiWiRepositoryConnectionTest.java
new file mode 100644
index 0000000..f71f964
--- /dev/null
+++ b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/sesame/repository/KiWiRepositoryConnectionTest.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.marmotta.kiwi.test.sesame.repository;
+
+import org.apache.marmotta.kiwi.config.KiWiConfiguration;
+import org.apache.marmotta.kiwi.persistence.h2.H2Dialect;
+import org.apache.marmotta.kiwi.sail.KiWiStore;
+import org.apache.marmotta.kiwi.test.junit.KiWiDatabaseRunner;
+import org.junit.runner.RunWith;
+import org.openrdf.repository.Repository;
+import org.openrdf.repository.RepositoryConnectionTest;
+import org.openrdf.repository.sail.SailRepository;
+import org.openrdf.sail.Sail;
+import org.openrdf.sail.SailException;
+import org.openrdf.sail.helpers.SailWrapper;
+
+import java.sql.SQLException;
+
+import static org.junit.Assert.fail;
+
+/**
+ * Run the {@link RepositoryConnectionTest}s.
+ * @author Jakob Frank <ja...@apache.org>
+ *
+ */
+@RunWith(KiWiDatabaseRunner.class)
+public class KiWiRepositoryConnectionTest extends RepositoryConnectionTest {
+
+ private final KiWiConfiguration config;
+
+ public KiWiRepositoryConnectionTest(KiWiConfiguration config) {
+ this.config = config;
+ }
+
+ /* (non-Javadoc)
+ * @see org.openrdf.repository.RepositoryConnectionTest#createRepository()
+ */
+ @Override
+ protected Repository createRepository() throws Exception {
+ config.setDefaultContext(null);
+ Sail store = new SailWrapper(new KiWiStore(config)) {
+ @Override
+ public void shutDown() throws SailException {
+ try {
+ ((KiWiStore)getBaseSail()).getPersistence().dropDatabase();
+ } catch (SQLException e) {
+ fail("SQL exception while deleting database");
+ }
+
+ super.shutDown();
+ }
+ };
+ return new SailRepository(store);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/sesame/repository/KiWiRepositoryTest.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/sesame/repository/KiWiRepositoryTest.java b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/sesame/repository/KiWiRepositoryTest.java
new file mode 100644
index 0000000..7291859
--- /dev/null
+++ b/libraries/kiwi/kiwi-triplestore/src/test/java/org/apache/marmotta/kiwi/test/sesame/repository/KiWiRepositoryTest.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.marmotta.kiwi.test.sesame.repository;
+
+import org.apache.marmotta.kiwi.config.KiWiConfiguration;
+import org.apache.marmotta.kiwi.sail.KiWiStore;
+import org.apache.marmotta.kiwi.test.junit.KiWiDatabaseRunner;
+import org.junit.Ignore;
+import org.junit.runner.RunWith;
+import org.openrdf.repository.Repository;
+import org.openrdf.repository.RepositoryTest;
+import org.openrdf.repository.sail.SailRepository;
+import org.openrdf.sail.Sail;
+import org.openrdf.sail.SailException;
+import org.openrdf.sail.helpers.SailWrapper;
+
+import java.sql.SQLException;
+
+import static org.junit.Assert.fail;
+
+/**
+ * Run the {@link RepositoryTest}s.
+ * @author Jakob Frank <ja...@apache.org>
+ *
+ */
+@RunWith(KiWiDatabaseRunner.class)
+public class KiWiRepositoryTest extends RepositoryTest {
+
+ private final KiWiConfiguration config;
+
+ private KiWiStore store;
+
+ public KiWiRepositoryTest(KiWiConfiguration config) {
+ this.config = config;
+ }
+
+ /* (non-Javadoc)
+ * @see org.openrdf.repository.RepositoryTest#createRepository()
+ */
+ @Override
+ protected Repository createRepository() throws Exception {
+ store = new KiWiStore(config);
+ return new SailRepository(store);
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ store.getPersistence().dropDatabase();
+ super.tearDown();
+ }
+}
http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-tripletable/pom.xml
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-tripletable/pom.xml b/libraries/kiwi/kiwi-tripletable/pom.xml
index 3aa74e9..2c8a49d 100644
--- a/libraries/kiwi/kiwi-tripletable/pom.xml
+++ b/libraries/kiwi/kiwi-tripletable/pom.xml
@@ -21,7 +21,7 @@
<parent>
<groupId>org.apache.marmotta</groupId>
<artifactId>kiwi-parent</artifactId>
- <version>3.1.0-incubating-SNAPSHOT</version>
+ <version>3.1.0-incubating</version>
</parent>
<artifactId>kiwi-tripletable</artifactId>
@@ -46,6 +46,42 @@
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.marmotta</groupId>
+ <artifactId>marmotta-commons</artifactId>
+ </dependency>
+
+ <dependency>
+ <artifactId>junit</artifactId>
+ <groupId>junit</groupId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <artifactId>hamcrest-core</artifactId>
+ <groupId>org.hamcrest</groupId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <artifactId>hamcrest-library</artifactId>
+ <groupId>org.hamcrest</groupId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ <scope>test</scope>
+ </dependency>
+
</dependencies>
</project>
http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-tripletable/src/main/java/org/apache/marmotta/kiwi/model/caching/IntArray.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-tripletable/src/main/java/org/apache/marmotta/kiwi/model/caching/IntArray.java b/libraries/kiwi/kiwi-tripletable/src/main/java/org/apache/marmotta/kiwi/model/caching/IntArray.java
index f870611..549bddf 100644
--- a/libraries/kiwi/kiwi-tripletable/src/main/java/org/apache/marmotta/kiwi/model/caching/IntArray.java
+++ b/libraries/kiwi/kiwi-tripletable/src/main/java/org/apache/marmotta/kiwi/model/caching/IntArray.java
@@ -44,12 +44,16 @@ public final class IntArray implements Comparable<IntArray> {
public IntArray(int[] data) {
this.data = data;
+ }
- Hasher hasher = hashFunction.newHasher();
- for(int i : data) {
- hasher.putInt(i);
+ private void ensureHashCode() {
+ if(goodHashCode == null) {
+ Hasher hasher = hashFunction.newHasher();
+ for(int i : data) {
+ hasher.putInt(i);
+ }
+ goodHashCode = hasher.hash();
}
- goodHashCode = hasher.hash();
}
public static final IntArray createSPOCKey(Resource subject, URI property, Value object, Resource context){
@@ -72,7 +76,7 @@ public final class IntArray implements Comparable<IntArray> {
}
- public static final IntArray createSPOCMaxKey(Resource subject, URI property, Value object, URI context){
+ public static final IntArray createSPOCMaxKey(Resource subject, URI property, Value object, Resource context){
// the cache key is generated by appending the bytes of the hashcodes of subject, property, object, context and inferred and
// storing them as a BigInteger; generating the cache key should thus be very efficient
@@ -112,7 +116,7 @@ public final class IntArray implements Comparable<IntArray> {
}
- public static final IntArray createCSPOMaxKey(Resource subject, URI property, Value object, URI context){
+ public static final IntArray createCSPOMaxKey(Resource subject, URI property, Value object, Resource context){
// the cache key is generated by appending the bytes of the hashcodes of subject, property, object, context and inferred and
// storing them as a BigInteger; generating the cache key should thus be very efficient
@@ -165,6 +169,7 @@ public final class IntArray implements Comparable<IntArray> {
@Override
public int hashCode() {
+ ensureHashCode();
return goodHashCode.hashCode();
}
}
http://git-wip-us.apache.org/repos/asf/marmotta/blob/582abb5b/libraries/kiwi/kiwi-tripletable/src/main/java/org/apache/marmotta/kiwi/model/caching/TripleTable.java
----------------------------------------------------------------------
diff --git a/libraries/kiwi/kiwi-tripletable/src/main/java/org/apache/marmotta/kiwi/model/caching/TripleTable.java b/libraries/kiwi/kiwi-tripletable/src/main/java/org/apache/marmotta/kiwi/model/caching/TripleTable.java
index 8b40ca5..d05b644 100644
--- a/libraries/kiwi/kiwi-tripletable/src/main/java/org/apache/marmotta/kiwi/model/caching/TripleTable.java
+++ b/libraries/kiwi/kiwi-tripletable/src/main/java/org/apache/marmotta/kiwi/model/caching/TripleTable.java
@@ -18,21 +18,16 @@
package org.apache.marmotta.kiwi.model.caching;
import com.google.common.base.Predicate;
-import com.google.common.collect.Sets;
+import com.google.common.collect.Collections2;
+import org.apache.marmotta.commons.collections.EquivalenceHashSet;
+import org.apache.marmotta.commons.sesame.model.StatementCommons;
import org.openrdf.model.Resource;
import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import java.io.Serializable;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.NavigableMap;
-import java.util.Set;
-import java.util.TreeMap;
+import java.util.*;
/**
* A triple table that allows efficient in-memory operations over large collections of triples. This can be used as
@@ -61,14 +56,14 @@ public class TripleTable<Triple extends Statement> implements Set<Triple>, Seria
private NavigableMap<IntArray,Triple> indexCSPO;
public TripleTable() {
- data = new HashSet<Triple>();
+ data = StatementCommons.newQuadrupleSet();
indexSPOC = new TreeMap<IntArray, Triple>();
indexCSPO = new TreeMap<IntArray, Triple>();
}
public TripleTable(Collection<Triple> triples) {
- data = new HashSet<Triple>(triples.size());
+ data = StatementCommons.newQuadrupleSet();
indexSPOC = new TreeMap<IntArray, Triple>();
indexCSPO = new TreeMap<IntArray, Triple>();
addAll(triples);
@@ -83,7 +78,7 @@ public class TripleTable<Triple extends Statement> implements Set<Triple>, Seria
* @return the number of elements in this set (its cardinality)
*/
@Override
- public int size() {
+ public synchronized int size() {
return data.size();
}
@@ -93,7 +88,7 @@ public class TripleTable<Triple extends Statement> implements Set<Triple>, Seria
* @return <tt>true</tt> if this set contains no elements
*/
@Override
- public boolean isEmpty() {
+ public synchronized boolean isEmpty() {
return data.isEmpty();
}
@@ -111,7 +106,7 @@ public class TripleTable<Triple extends Statement> implements Set<Triple>, Seria
* set does not permit null elements (optional)
*/
@Override
- public boolean contains(Object o) {
+ public synchronized boolean contains(Object o) {
return data.contains(o);
}
@@ -144,7 +139,7 @@ public class TripleTable<Triple extends Statement> implements Set<Triple>, Seria
* @return an array containing all the elements in this set
*/
@Override
- public Object[] toArray() {
+ public synchronized Object[] toArray() {
return data.toArray();
}
@@ -191,7 +186,7 @@ public class TripleTable<Triple extends Statement> implements Set<Triple>, Seria
* @throws NullPointerException if the specified array is null
*/
@Override
- public <T> T[] toArray(T[] a) {
+ public synchronized <T> T[] toArray(T[] a) {
return data.toArray(a);
}
@@ -226,7 +221,7 @@ public class TripleTable<Triple extends Statement> implements Set<Triple>, Seria
* prevents it from being added to this set
*/
@Override
- public boolean add(Triple triple) {
+ public synchronized boolean add(Triple triple) {
indexSPOC.put(IntArray.createSPOCKey(triple.getSubject(), triple.getPredicate(), triple.getObject(), triple.getContext()),triple);
indexCSPO.put(IntArray.createCSPOKey(triple.getSubject(), triple.getPredicate(), triple.getObject(), triple.getContext()),triple);
return data.add(triple);
@@ -252,7 +247,7 @@ public class TripleTable<Triple extends Statement> implements Set<Triple>, Seria
* is not supported by this set
*/
@Override
- public boolean remove(Object o) {
+ public synchronized boolean remove(Object o) {
if(o instanceof Statement) {
Statement triple = (Statement)o;
indexSPOC.remove(IntArray.createSPOCKey(triple.getSubject(), triple.getPredicate(), triple.getObject(), triple.getContext()));
@@ -278,7 +273,7 @@ public class TripleTable<Triple extends Statement> implements Set<Triple>, Seria
* @see #contains(Object)
*/
@Override
- public boolean containsAll(Collection<?> c) {
+ public synchronized boolean containsAll(Collection<?> c) {
return data.containsAll(c);
}
@@ -305,7 +300,7 @@ public class TripleTable<Triple extends Statement> implements Set<Triple>, Seria
* @see #add(Object)
*/
@Override
- public boolean addAll(Collection<? extends Triple> c) {
+ public synchronized boolean addAll(Collection<? extends Triple> c) {
boolean modified = false;
for(Triple t : c) {
modified = add(t) || modified;
@@ -333,7 +328,7 @@ public class TripleTable<Triple extends Statement> implements Set<Triple>, Seria
* @see #remove(Object)
*/
@Override
- public boolean retainAll(Collection<?> c) {
+ public synchronized boolean retainAll(Collection<?> c) {
Iterator<Map.Entry<IntArray,Triple>> it = indexSPOC.entrySet().iterator();
while(it.hasNext()) {
if(!c.contains(it.next().getValue())) {
@@ -369,7 +364,7 @@ public class TripleTable<Triple extends Statement> implements Set<Triple>, Seria
* @see #contains(Object)
*/
@Override
- public boolean removeAll(Collection<?> c) {
+ public synchronized boolean removeAll(Collection<?> c) {
boolean modified = false;
for(Object o : c) {
modified = remove(o) || modified;
@@ -385,7 +380,7 @@ public class TripleTable<Triple extends Statement> implements Set<Triple>, Seria
* is not supported by this set
*/
@Override
- public void clear() {
+ public synchronized void clear() {
data.clear();
indexSPOC.clear();
indexCSPO.clear();
@@ -394,13 +389,15 @@ public class TripleTable<Triple extends Statement> implements Set<Triple>, Seria
/**
* Return a subset of the triples matching the filter criteria. Arguments with null value are treated as wildcards.
*
+ *
* @param subject
* @param property
* @param object
* @param context
+ * @param wildcardContext
* @return
*/
- public Collection<Triple> listTriples(final Resource subject, final URI property, final Value object, final URI context) {
+ public synchronized Collection<Triple> listTriples(final Resource subject, final URI property, final Value object, final Resource context, boolean wildcardContext) {
// in special cases we can make use of the index
if(subject != null && property != null && object != null && context != null) {
IntArray key = IntArray.createSPOCKey(subject, property, object, context);
@@ -410,9 +407,10 @@ public class TripleTable<Triple extends Statement> implements Set<Triple>, Seria
} else {
return Collections.emptyList();
}
- } else if( (subject != null && property != null && object != null)
+ } else if(wildcardContext &&
+ ( (subject != null && property != null && object != null)
|| (subject != null && property != null)
- || subject != null) {
+ || subject != null)) {
IntArray fromKey = IntArray.createSPOCKey(subject, property, object, context);
IntArray toKey = IntArray.createSPOCMaxKey(subject, property, object, context);
@@ -446,13 +444,20 @@ public class TripleTable<Triple extends Statement> implements Set<Triple>, Seria
}
};
- return Sets.filter(data, p);
+ return Collections2.filter(data, p);
}
}
+ public synchronized Collection<Resource> listContextIDs() {
+ Set<Resource> result = new HashSet<>();
+ for(Triple t : data) {
+ result.add(t.getContext());
+ }
+ return result;
+ }
@Override
- public boolean equals(Object o) {
+ public synchronized boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
@@ -465,7 +470,9 @@ public class TripleTable<Triple extends Statement> implements Set<Triple>, Seria
}
@Override
- public int hashCode() {
+ public synchronized int hashCode() {
return data.hashCode();
}
+
+
}