Index: gs2-extensions/tdb/trunk/src/java/org/greenstone/gsdl3/util/TDBWrapper.java
===================================================================
--- gs2-extensions/tdb/trunk/src/java/org/greenstone/gsdl3/util/TDBWrapper.java	(revision 30269)
+++ gs2-extensions/tdb/trunk/src/java/org/greenstone/gsdl3/util/TDBWrapper.java	(revision 30269)
@@ -0,0 +1,214 @@
+/*
+ *    TDBWrapper.java
+ *    Copyright (C) 2015 New Zealand Digital Library, http://www.nzdl.org
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.greenstone.gsdl3.util;
+
+import java.net.URLEncoder;
+import java.util.Enumeration;
+
+import org.apache.log4j.Logger;
+import org.greenstone.gsdl3.util.DBHelper;
+import org.greenstone.gsdl3.util.FlatDatabaseWrapper;
+
+import org.greenstone.tdbjava.TDBJava;
+
+/**
+ * Java wrapper class for TDB - uses TDBJava (a JNI wrapper to TDB)
+ */
+public class TDBWrapper
+    implements FlatDatabaseWrapper
+{
+    // A logger for messaging (mostly error)
+    static Logger logger = Logger.getLogger(org.greenstone.gsdl3.util.TDBWrapper.class.getName());
+
+    static
+    {
+	/** Register this Wrapper with the DBHelper */
+	DBHelper.registerDBTypeExt("tdb",".tdb");
+	logger.info("Registered TDB database type with file extension .tdb");
+    }
+
+    // The open database (if any)
+    protected TDBJava db_ = null;
+
+
+    /** @function openDatabase(String, int)
+     *  Open the database filename, with mode mode
+     */
+    public boolean openDatabase(String filename, int mode)
+    {
+	// convert mode to TDBJava open mode
+	if (mode == this.READ) {
+	    mode = TDBJava.O_READONLY;
+	}
+	else if (mode == this.WRITE) {
+	    mode = TDBJava.O_DEFAULT;
+	}
+	else {
+	    logger.error("invalid mode, " + mode + ", opening db for reading only");
+	    mode = TDBJava.O_READONLY;
+	}
+
+	try {
+	    if (this.db_ != null) {
+		this.db_.close();
+	    }
+	    this.db_ = new TDBJava(filename, TDBJava.TDB_DEFAULT, mode);
+	}
+	catch (Exception e) {
+	    logger.error("couldn't open database: " + filename);
+	    logger.error("  Exception: " + e.toString());
+	    return false;
+	}
+	logger.info("opened with tdb_flags=" + TDBJava.TDB_DEFAULT + " and mode=" + mode);
+	return true;
+    }
+    /** openDatabase(String, int) **/
+
+
+    /** @function closeDatabase
+     *  Close the database associated with this wrapper
+     */
+    public void closeDatabase()
+    {
+	if (this.db_ != null) {
+	    try {
+		this.db_.close();
+		this.db_ = null;
+		// Hack: force Windows to let go of the gdb file
+		if (System.getProperty("os.name").startsWith("Windows")) {
+		    System.gc();
+		}
+	    }
+	    catch (Exception e) {
+		logger.error("error on close()");
+		logger.error("  Exception: " + e.toString());
+	    }
+	}
+    }
+    /** closeDatabase() **/
+
+    /** @function getValue(String)
+     */
+    public String getValue(String key)
+    {
+	String value = null;
+	if (null != this.db_) {
+	    try {
+		value = this.db_.fetch(key);
+	    }
+	    catch (Exception e) {
+		logger.error("error on getValue(" + key + ")");
+		logger.error("  Exception: " + e.toString());
+	    }
+	}
+	if (null == value) {
+	    logger.error("key " + key + " not present in db");
+	}
+	return value;
+    }
+    /** getValue(String) **/
+
+    /** @function setValue(String, String)
+     *  Sets the given key to the given value in the database
+     */
+    public boolean setValue(String key, String value)
+    {
+	boolean result = false;
+	if (this.db_ == null) {
+	    logger.error("database is not open");
+	}
+	else if (!this.db_.isWritable()) {
+	    logger.error("database is read-only");
+	}
+	else {
+	    try {
+		this.db_.store(key, value);
+		result = true;
+	    }
+	    catch (Exception e) {
+		logger.error("error storing " + key + " = " + value);
+		logger.error("  Exception: " + e.toString());
+	    }
+	}
+	return result;
+    }
+    /** setValue(String, String) **/
+
+    /** @function deleteKey(String key)
+     *  Deletes the entry for given key
+     */
+    public boolean deleteKey(String key)
+    {
+	boolean result = false;
+	if (null == this.db_) {
+	    logger.error("database is not open");
+	}
+	else if (!this.db_.isWritable()) {
+	    logger.error("database is read-only");
+	}
+	else {
+	    try {
+		this.db_.delete(key);
+		result = true;
+	    }
+	    catch (Exception e) {
+		logger.error("error deleting key " + key);
+		logger.error("  Exception: " + e.toString());
+	    }
+	}
+	return result;
+    }
+    /** deleteKey(String) **/
+
+    /** @function displayAllEntries()
+     *  Returns a string of key-value entries that can be printed for debugging
+     * purposes.
+     */
+    public String displayAllEntries()
+    {
+	StringBuffer output = new StringBuffer();
+	if (null == this.db_) {
+	    logger.error("database is not open");
+	}
+	else {
+	    try {
+		Enumeration keys = this.db_.keys();
+		while (keys.hasMoreElements()) {
+		    String key = (String) keys.nextElement();
+		    String value = this.db_.fetch(key);
+		    String urlkey = URLEncoder.encode((String) key, "UTF8");
+		    output.append("key href: ");
+		    output.append(key);
+		    output.append("\tvalue ID: ");
+		    output.append(value);
+		    output.append("\n");
+		    output.append("URL encoded key: " + urlkey);
+		}
+	    }
+	    catch (Exception e) {
+		logger.error("error when trying to display all entries");
+		logger.error("  Exception: " + e.toString());
+	    }
+	}
+	return output.toString();
+    }
+    /** displayAllEntries() **/
+    
+}
+/** Class: TDBWrapper **/
