Revision: 1825
Author: [email protected]
Date: Sun Jan 31 14:02:00 2010
Log: Add support for Jena database types SDB and TDB. Also upgrade Jena to
2.6.2. Needed to add support of Joseki. Type of database used at runtime
can be configured.
new review
update issue 116
Add support for Jena database types SDB and TDB. Also upgrade Jena to
2.6.2. Needed to add support of Joseki. Type of database used at runtime
can be configured.
http://code.google.com/p/simal/source/detail?r=1825
Added:
/trunk/uk.ac.osswatch.simal.core/src/main/java/uk/ac/osswatch/simal/model/jena/simal/JenaDatabaseSupport.java
/trunk/uk.ac.osswatch.simal.core/src/test/java/uk/ac/osswatch/simal/model/jena/simal/TestJenaDatabaseSupport.java
Modified:
/trunk/uk.ac.osswatch.simal.core
/trunk/uk.ac.osswatch.simal.core/pom.xml
/trunk/uk.ac.osswatch.simal.core/src/main/java/uk/ac/osswatch/simal/SimalProperties.java
/trunk/uk.ac.osswatch.simal.core/src/main/java/uk/ac/osswatch/simal/model/jena/simal/JenaSimalRepository.java
/trunk/uk.ac.osswatch.simal.core/src/main/resources/default.simal.properties
/trunk/uk.ac.osswatch.simal.core/src/test/java/uk/ac/osswatch/simal/integrationTest/service/TestProjectService.java
=======================================
--- /dev/null
+++
/trunk/uk.ac.osswatch.simal.core/src/main/java/uk/ac/osswatch/simal/model/jena/simal/JenaDatabaseSupport.java
Sun Jan 31 14:02:00 2010
@@ -0,0 +1,251 @@
+/*
+ * Copyright 2010 University of Oxford
+ *
+ * Licensed 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 uk.ac.osswatch.simal.model.jena.simal;
+
+import java.sql.SQLException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import uk.ac.osswatch.simal.SimalProperties;
+import uk.ac.osswatch.simal.rdf.SimalRepositoryException;
+
+import com.hp.hpl.jena.db.DBConnection;
+import com.hp.hpl.jena.db.IDBConnection;
+import com.hp.hpl.jena.rdf.model.Model;
+import com.hp.hpl.jena.rdf.model.ModelFactory;
+import com.hp.hpl.jena.rdf.model.ModelMaker;
+import com.hp.hpl.jena.sdb.SDBFactory;
+import com.hp.hpl.jena.sdb.Store;
+import com.hp.hpl.jena.sdb.StoreDesc;
+import com.hp.hpl.jena.sdb.sql.SDBConnectionDesc;
+import com.hp.hpl.jena.sdb.sql.SDBExceptionSQL;
+import com.hp.hpl.jena.sdb.store.DatabaseType;
+import com.hp.hpl.jena.sdb.store.LayoutType;
+import com.hp.hpl.jena.tdb.TDBFactory;
+
+/**
+ * Helper for Jena repository functions. Performs
+ * all database type specific operations. Supports
+ * types RDB, SDB and TDB.
+ */
+public class JenaDatabaseSupport {
+ public static final Logger LOGGER = LoggerFactory
+ .getLogger(JenaSimalRepository.class);
+
+ /**
+ * Token for the type of database; determined at
+ * runtime. These are all the database types that
+ * Jena supports.
+ */
+ public static enum JenaDatabaseType {
+ RDB, SDB, TDB;
+ };
+
+ private JenaDatabaseType type = null;
+
+ private StoreDesc cachedStoreDesc = null;
+
+ /**
+ * Intialise the Jena database with the specific type
+ * and store the database in the directory specified.
+ * @param valueOf
+ * @param directory
+ * @throws SimalRepositoryException
+ */
+ public Model initialiseDatabase(String dbType, String directory)
+ throws SimalRepositoryException {
+ Model model = null;
+
+ try {
+ type = JenaDatabaseType.valueOf(dbType);
+ } catch (IllegalArgumentException e) {
+ LOGGER.warn("Illegal dbType " + dbType + "; using RDB");
+ type = JenaDatabaseType.RDB;
+ }
+
+ switch (type) {
+ case SDB:
+ Store store = initialiseSDBStore(directory, dbType);
+ model = SDBFactory.connectDefaultModel(store);
+ //model = SDBFactory.connectDefaultModel(generateStoreDescSdb());
+ break;
+ case TDB:
+ String tdbUrl = constructDatabasePath(directory, dbType);
+ LOGGER.debug("Creating TDB database with URL " + tdbUrl);
+ model = TDBFactory.createModel(tdbUrl);
+
+ break;
+ case RDB:
+ default:
+ model = initialiseRdbModel(directory, dbType);
+ }
+
+ return model;
+ }
+
+ /**
+ * Specific initialisation for RDB.
+ * @param directory
+ * @param dbType
+ * @return
+ * @throws SimalRepositoryException
+ */
+ private Model initialiseRdbModel(String directory, String dbType)
+ throws SimalRepositoryException {
+ initialiseDerbyDatabase();
+
+ String jdbcUrl = "jdbc:derby:" + constructDatabasePath(directory,
dbType)
+ + ";create=true";
+ String jdbcUser = "";
+ String jdbcPassword = "";
+ String jdbcType = "Derby";
+
+ // Create database connection
+ LOGGER.debug("Creating RDB database with URL " + jdbcUrl);
+ IDBConnection conn = new DBConnection(jdbcUrl, jdbcUser, jdbcPassword,
jdbcType);
+ ModelMaker maker = ModelFactory.createModelRDBMaker(conn);
+
+ // create or open the default model
+ Model model = maker.createDefaultModel();
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ LOGGER.warn("Could not close connection; " + e.getMessage());
+ }
+
+ return model;
+ }
+
+ /**
+ * Generates the Store description that contains all
+ * parameters needed to connect to the store. Only used
+ * for SDB; result can be cached to reconnect to the store.
+ * @param dbUrl
+ * @return
+ */
+ private StoreDesc generateStoreDescSdb(String dbUrl) {
+ StoreDesc storeDesc = new StoreDesc(LayoutType.LayoutTripleNodesHash,
DatabaseType.Derby);
+
+ SDBConnectionDesc sdbConnDesc = SDBConnectionDesc.blank();
+ sdbConnDesc.setJdbcURL(dbUrl);
+ sdbConnDesc.setUser("");
+ sdbConnDesc.setPassword("");
+
+ storeDesc.connDesc = sdbConnDesc;
+
+ return storeDesc;
+ }
+
+ /**
+ * Specific initialisation for the SDB store. The store
+ * is used for Jena databases of type SDB to connect to
+ * or generate a Model.
+ *
+ * @param directory
+ * @return
+ * @throws SimalRepositoryException
+ */
+ private Store initialiseSDBStore(String directory, String dbType)
+ throws SimalRepositoryException {
+ initialiseDerbyDatabase();
+
+ String dbUrl = "jdbc:derby:" + constructDatabasePath(directory, dbType)
+ + ";create=true";
+ StoreDesc storeDesc = generateStoreDescSdb(dbUrl);
+ Store store = SDBFactory.connectStore(storeDesc);
+
+ try {
+ store.getSize();
+ LOGGER.info("Connected to existing SDB store");
+ } catch (SDBExceptionSQL e) {
+ LOGGER.info("Creating new SDB store because it does not exist;");
+ store.getTableFormatter().format();
+ }
+ this.cachedStoreDesc = storeDesc;
+ return store;
+ }
+
+ /**
+ * Constructs the database path; this is used for all types
+ * of Jena databases.
+ * @param directory
+ * @param dbType
+ * @return
+ * @throws SimalRepositoryException
+ */
+ protected static String constructDatabasePath(String directory, String
dbType)
+ throws SimalRepositoryException {
+ StringBuffer databasePath = new StringBuffer();
+
+ if (directory != null && !directory.equals("")) {
+ databasePath.append(directory);
+ } else {
+ databasePath.append(SimalProperties
+ .getProperty(SimalProperties.PROPERTY_RDF_DATA_DIR));
+ }
+
+ databasePath.append(System.getProperty("file.separator"));
+ databasePath.append(SimalProperties
+ .getProperty(SimalProperties.PROPERTY_RDF_DATA_FILENAME));
+ databasePath.append('_');
+ databasePath.append(dbType);
+
+ return databasePath.toString();
+ }
+
+ /**
+ * Simple initialiser to make sure the Derby driver is loaded.
+ * @throws SimalRepositoryException
+ */
+ private static void initialiseDerbyDatabase() throws
SimalRepositoryException {
+ String className = "org.apache.derby.jdbc.EmbeddedDriver";
+
+ try {
+ Class.forName(className);
+ } catch (ClassNotFoundException e) {
+ throw new SimalRepositoryException("Unable to find derby driver", e);
+ }
+ }
+
+ /**
+ * Removes all the data from the model. Performs the deletion
+ * specific to the type of database, as determined at runtime.
+ * @param model
+ */
+ public Model removeAllData(Model model) {
+ Model newModel = null;
+
+ switch (type) {
+ case SDB:
+ Store store = SDBFactory.connectStore(cachedStoreDesc);
+ store.getTableFormatter().truncate();
+ newModel = SDBFactory.connectDefaultModel(store);
+ break;
+ case TDB:
+ case RDB:
+ default:
+ model.removeAll();
+ newModel = model;
+ }
+
+ return newModel;
+ }
+
+}
=======================================
--- /dev/null
+++
/trunk/uk.ac.osswatch.simal.core/src/test/java/uk/ac/osswatch/simal/model/jena/simal/TestJenaDatabaseSupport.java
Sun Jan 31 14:02:00 2010
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2010 University of Oxford
+ *
+ * Licensed 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 uk.ac.osswatch.simal.model.jena.simal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.io.FileUtils;
+import org.junit.AfterClass;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import uk.ac.osswatch.simal.rdf.SimalRepositoryException;
+
+import com.hp.hpl.jena.db.ModelRDB;
+import com.hp.hpl.jena.rdf.model.Model;
+import com.hp.hpl.jena.rdf.model.impl.ModelCom;
+
+/**
+ * Test all supporting databases of JenaDatabaseSupport.
+ */
+public class TestJenaDatabaseSupport {
+ public static final Logger LOGGER = LoggerFactory
+ .getLogger(JenaSimalRepository.class);
+
+ @AfterClass
+ public static void removeTestDatabases() {
+ deleteTestDatabase("SDB", "");
+ deleteTestDatabase("TDB", "");
+ deleteTestDatabase("RDB", "");
+ }
+
+ /**
+ * Make sure the database is deleted when test is completed.
+ */
+ private static void deleteTestDatabase(String dbType, String directory) {
+ try {
+ String dbPath = JenaDatabaseSupport.constructDatabasePath(directory,
+ dbType);
+ File dbFolder = new File(dbPath);
+ try {
+ FileUtils.deleteDirectory(dbFolder);
+ } catch (IOException e) {
+ // TODO For now ignore failure of deleting test db; Many times
some db
+ // files are still locked, it's not clear how to explicitly
disconnect
+ // from the db. For now we delete the test folder additionally
before
+ // running the tests.
+ LOGGER.info("Test failed to delete database from path " +
dbFolder);
+ }
+ } catch (SimalRepositoryException e) {
+ fail("Could not contruct database path from directory " + directory);
+ }
+ }
+
+ @Test
+ public void testDatabaseInitialisationSDB() {
+ performDatabaseInitialisationTest("SDB", ModelCom.class);
+ }
+
+ @Test
+ public void testDatabaseInitialisationTDB() {
+ performDatabaseInitialisationTest("TDB", ModelCom.class);
+ }
+
+ @Test
+ public void testDatabaseInitialisationRDB() {
+ performDatabaseInitialisationTest("RDB", ModelRDB.class);
+ }
+
+ @SuppressWarnings("unchecked")
+ private void performDatabaseInitialisationTest(String dbType,
+ Class expectedClass) {
+ String directory = "";
+ deleteTestDatabase(dbType, directory);
+ JenaDatabaseSupport jenaDatabaseSupport = new JenaDatabaseSupport();
+ try {
+ Model model = jenaDatabaseSupport.initialiseDatabase(dbType,
directory);
+ assertEquals(expectedClass, model.getClass());
+ jenaDatabaseSupport.removeAllData(model);
+ model.close();
+ model = null;
+ } catch (SimalRepositoryException e) {
+ fail("Unexpectedly failed init");
+ }
+ }
+}
=======================================
--- /trunk/uk.ac.osswatch.simal.core/pom.xml Mon Nov 30 16:36:24 2009
+++ /trunk/uk.ac.osswatch.simal.core/pom.xml Sun Jan 31 14:02:00 2010
@@ -97,6 +97,14 @@
<id>simal</id>
<url>http://www.16degrees.com.au/maven</url>
</repository>
+ <repository>
+ <id>jena</id>
+ <url>http://openjena.org/repo/</url>
+ </repository>
+ <repository>
+ <id>joseki</id>
+ <url>http://openjena.org/repo-dev/</url>
+ </repository>
</repositories>
<dependencies>
@@ -111,7 +119,7 @@
<dependency>
<groupId>com.hp.hpl.jena</groupId>
<artifactId>jena</artifactId>
- <version>2.5.7</version>
+ <version>2.6.2</version>
<exclusions>
<exclusion>
<groupId>xerces</groupId>
@@ -120,6 +128,18 @@
</exclusions>
</dependency>
+ <dependency>
+ <groupId>com.hp.hpl.jena</groupId>
+ <artifactId>sdb</artifactId>
+ <version>1.3.1</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.hp.hpl.jena</groupId>
+ <artifactId>tdb</artifactId>
+ <version>0.8.4</version>
+ </dependency>
+
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
@@ -297,7 +317,7 @@
<exclude>derby.log</exclude>
<exclude>repository/**/*</exclude>
<exclude>reports/**/*</exclude>
- <exclude>simal/**/*</exclude>
+ <exclude>simal*/**/*</exclude>
<exclude>build/**/*</exclude>
<exclude>simalDOAPFilestore/**/*</exclude>
<exclude>simalRepository/**/*</exclude>
=======================================
---
/trunk/uk.ac.osswatch.simal.core/src/main/java/uk/ac/osswatch/simal/SimalProperties.java
Fri Nov 13 08:43:08 2009
+++
/trunk/uk.ac.osswatch.simal.core/src/main/java/uk/ac/osswatch/simal/SimalProperties.java
Sun Jan 31 14:02:00 2010
@@ -54,6 +54,7 @@
public static final String PROPERTY_SIMAL_NEXT_REVIEW_ID
= "simal.nextReviewID";
public static final String PROPERTY_SIMAL_NEXT_RELEASE_ID
= "simal.nextReleaseID";
public static final String PROPERTY_SIMAL_DOAP_FILE_STORE
= "simal.doap.filestore";
+ public static final String PROPERTY_SIMAL_DB_TYPE = "simal.db.type";
public static final String PROPERTY_LOCAL_PROPERTIES_LOCATION
= "simal.local.properties.path";
@@ -103,6 +104,7 @@
logger.debug("No local.simal.properties file was found");
localProps = new Properties();
}
+ localProps.putAll(System.getProperties());
}
/**
=======================================
---
/trunk/uk.ac.osswatch.simal.core/src/main/java/uk/ac/osswatch/simal/model/jena/simal/JenaSimalRepository.java
Fri Jan 8 08:23:04 2010
+++
/trunk/uk.ac.osswatch.simal.core/src/main/java/uk/ac/osswatch/simal/model/jena/simal/JenaSimalRepository.java
Sun Jan 31 14:02:00 2010
@@ -74,8 +74,6 @@
import uk.ac.osswatch.simal.rdf.io.RDFUtils;
import uk.ac.osswatch.simal.service.jena.JenaProjectService;
-import com.hp.hpl.jena.db.DBConnection;
-import com.hp.hpl.jena.db.IDBConnection;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryException;
import com.hp.hpl.jena.query.QueryExecution;
@@ -85,7 +83,6 @@
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
-import com.hp.hpl.jena.rdf.model.ModelMaker;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Statement;
@@ -100,12 +97,15 @@
private transient Model model;
+ private transient JenaDatabaseSupport jenaDatabaseSupport;
+
/**
* Use getInstance instead.
*/
private JenaSimalRepository() {
super();
model = null;
+ jenaDatabaseSupport = new JenaDatabaseSupport();
}
/**
@@ -123,8 +123,8 @@
}
/**
- * Initialise the repository.
- *
+ * Initialise the Jena repository. Will determine type of database
+ * using property SimalProperties.PROPERTY_SIMAL_DB_TYPE.
* @param directory
* the directory for the database if it is a persistent
repository
* (i.e. not a test repo)
@@ -138,56 +138,24 @@
if (isTest) {
model = ModelFactory.createDefaultModel();
+ initialised = true;
+ initTestData();
} else {
- String className = "org.apache.derby.jdbc.EmbeddedDriver"; // path of
- // driver
- // class
- try {
- Class.forName(className);
- } catch (ClassNotFoundException e) {
- throw new SimalRepositoryException("Unable to find derby driver",
e);
- }
- String DB_URL;
- if (directory != null) {
- DB_URL = "jdbc:derby:"
- + directory
- + "/"
- + SimalProperties
- .getProperty(SimalProperties.PROPERTY_RDF_DATA_FILENAME)
- + ";create=true";
- } else {
- DB_URL = "jdbc:derby:"
- + SimalProperties
- .getProperty(SimalProperties.PROPERTY_RDF_DATA_DIR)
- + "/"
- + SimalProperties
- .getProperty(SimalProperties.PROPERTY_RDF_DATA_FILENAME)
- + ";create=true";
- }
- String DB_USER = "";
- String DB_PASSWD = "";
- String DB = "Derby";
-
- // Create database connection
- logger.debug("Creating DB with URL " + DB_URL);
- IDBConnection conn = new DBConnection(DB_URL, DB_USER, DB_PASSWD,
DB);
- ModelMaker maker = ModelFactory.createModelRDBMaker(conn);
-
- // create or open the default model
- model = maker.createDefaultModel();
-
- // Close the database connection
- // conn.close();
- }
-
- initialised = true;
-
- if (isTest) {
- try {
- ModelSupport.addTestData(this);
- } catch (Exception e) {
- throw new SimalRepositoryException("Unable to add test data",
e);
- }
+ String dbType =
SimalProperties.getProperty(SimalProperties.PROPERTY_SIMAL_DB_TYPE);
+ model = jenaDatabaseSupport.initialiseDatabase(dbType, directory);
+ initialised = true;
+ }
+ }
+
+ /**
+ * Initialise the test data, used when running in test mode.
+ * @throws SimalRepositoryException
+ */
+ private void initTestData() throws SimalRepositoryException {
+ try {
+ ModelSupport.addTestData(this);
+ } catch (Exception e) {
+ throw new SimalRepositoryException("Unable to add test data", e);
}
}
@@ -264,8 +232,11 @@
public void destroy() throws SimalRepositoryException {
logger.info("Destorying the SimalRepository");
- model.close();
- model = null;
+ if (model != null) {
+ model.close();
+ model = null;
+ }
+
initialised = false;
}
@@ -285,7 +256,6 @@
* @return
* @throws SimalRepositoryException
*/
- @SuppressWarnings("unchecked")
public SparqlResult getSparqlQueryResult(String queryStr)
throws SimalRepositoryException {
SparqlResult sparqlResult = null;
@@ -300,9 +270,9 @@
while (results.hasNext()) {
QuerySolution soln = results.nextSolution();
List<RDFNode> result = new ArrayList<RDFNode>();
- Iterator<Object> varNamesIter = soln.varNames();
+ Iterator<String> varNamesIter = soln.varNames();
while (varNamesIter.hasNext()) {
- String varName = (String) varNamesIter.next();
+ String varName = varNamesIter.next();
result.add(soln.get(varName));
}
sparqlResult.addResult(result);
@@ -432,7 +402,8 @@
}
public void removeAllData() {
- model.removeAll();
+ logger.warn("Removing all data from the repository.");
+ model = jenaDatabaseSupport.removeAllData(model);
}
/**
=======================================
---
/trunk/uk.ac.osswatch.simal.core/src/main/resources/default.simal.properties
Mon Nov 30 16:36:24 2009
+++
/trunk/uk.ac.osswatch.simal.core/src/main/resources/default.simal.properties
Sun Jan 31 14:02:00 2010
@@ -17,6 +17,9 @@
#simal.repository.dir=[the directory in which to store the simal
repository, defaults to user.dir]
simal.repository.filename=simal
simal.doap.filestore=simalDOAPFilestore
+# Database type; one of RDB, SDB, TDB
+simal.db.type=SDB
+
#simal.instance.id=[set to a human readable world unique identifier for
this instance of Simal , leave blank to have a unique identifier assigned
automatically]
simal.local.properties.path=local.simal.properties
simal.homepagelabels.filename=homepagelabels.properties
=======================================
---
/trunk/uk.ac.osswatch.simal.core/src/test/java/uk/ac/osswatch/simal/integrationTest/service/TestProjectService.java
Wed Nov 25 15:03:27 2009
+++
/trunk/uk.ac.osswatch.simal.core/src/test/java/uk/ac/osswatch/simal/integrationTest/service/TestProjectService.java
Sun Jan 31 14:02:00 2010
@@ -75,7 +75,7 @@
logger.debug("Project RDF is:\n" + project.toXML());
- String shortID =
testProjectID.substring(testProjectID.indexOf("-") + 1);
+ String shortID = testProjectID.substring(testProjectID.lastIndexOf("-")
+ 1);
project = service.getProjectById(shortID);
assertEquals("Got incorect project by ID","Simal DOAP Test",
project.getName());
}
--
You received this message because you are subscribed to the Google Groups "Simal
Commits" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/simal-commits?hl=en.